]> git.hungrycats.org Git - linux/commitdiff
[PATCH] scsi/imm.c cleanup and fixes (5/8)
authorAlexander Viro <viro@www.linux.org.uk>
Thu, 5 Feb 2004 01:39:40 +0000 (17:39 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Thu, 5 Feb 2004 01:39:40 +0000 (17:39 -0800)
* starting to kill imm_detect - we move the "probe a single port"
logics into a separate function and shift scanning into imm_driver_init().
Later that will give us a parport_driver ->attach().

drivers/scsi/imm.c

index c93f6d19a5c0b188681e3edbb45ecd82193cfc17..b056e7dd3e401b5dd3aeedded33942a8d037724b 100644 (file)
@@ -100,112 +100,98 @@ static inline void imm_pb_release(imm_struct *dev)
  *                   Parallel port probing routines                        *
  ***************************************************************************/
 
-static int imm_detect(Scsi_Host_Template * host)
+static Scsi_Host_Template imm_template;
+
+static int imm_probe(imm_struct *dev, struct parport *pb)
 {
-       struct Scsi_Host *hreg;
+       struct Scsi_Host *host;
        int ports;
-       int i, nhosts, try_again;
-       struct parport *pb;
+       int modes, ppb;
+       int err;
 
-       pb = parport_enumerate();
+       dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup,
+                                               NULL, 0, dev);
 
-       printk("imm: Version %s\n", IMM_VERSION);
-       nhosts = 0;
-       try_again = 0;
+       if (!dev->dev)
+               return -ENOMEM;
 
-       if (!pb) {
-               printk("imm: parport reports no devices.\n");
-               return 0;
+       /* Claim the bus so it remembers what we do to the control
+        * registers. [ CTR and ECP ]
+        */
+       err = -EBUSY;
+       if (imm_pb_claim(dev)) {
+               unsigned long now = jiffies;
+               while (dev->p_busy) {
+                       schedule();     /* We are safe to schedule here */
+                       if (time_after(jiffies, now + 3 * HZ)) {
+                               printk(KERN_ERR
+                                      "imm%d: failed to claim parport because a "
+                                      "pardevice is owning the port for too longtime!\n",
+                                      dev - imm_hosts);
+                               goto out;
+                       }
+               }
        }
-      retry_entry:
-       for (i = 0; pb; i++, pb = pb->next) {
-               imm_struct *dev = &imm_hosts[i];
-               int modes, ppb;
+       ppb = dev->base = dev->dev->port->base;
+       dev->base_hi = dev->dev->port->base_hi;
+       w_ctr(ppb, 0x0c);
+       modes = dev->dev->port->modes;
 
-               dev->dev =
-                   parport_register_device(pb, "imm", NULL, imm_wakeup,
-                                           NULL, 0, dev);
+       /* Mode detection works up the chain of speed
+        * This avoids a nasty if-then-else-if-... tree
+        */
+       dev->mode = IMM_NIBBLE;
 
-               if (!dev->dev)
-                       continue;
+       if (modes & PARPORT_MODE_TRISTATE)
+               dev->mode = IMM_PS2;
 
-               /* Claim the bus so it remembers what we do to the control
-                * registers. [ CTR and ECP ]
-                */
-               if (imm_pb_claim(dev)) {
-                       unsigned long now = jiffies;
-                       while (dev->p_busy) {
-                               schedule();     /* We are safe to schedule here */
-                               if (time_after(jiffies, now + 3 * HZ)) {
-                                       printk(KERN_ERR
-                                              "imm%d: failed to claim parport because a "
-                                              "pardevice is owning the port for too longtime!\n",
-                                              i);
-                                       parport_unregister_device(dev->dev);
-                                       return 0;
-                               }
-                       }
-               }
-               ppb = dev->base = dev->dev->port->base;
-               dev->base_hi = dev->dev->port->base_hi;
-               w_ctr(ppb, 0x0c);
-               modes = dev->dev->port->modes;
+       /* Done configuration */
 
-               /* Mode detection works up the chain of speed
-                * This avoids a nasty if-then-else-if-... tree
-                */
-               dev->mode = IMM_NIBBLE;
+       err = imm_init(dev);
 
-               if (modes & PARPORT_MODE_TRISTATE)
-                       dev->mode = IMM_PS2;
+       imm_pb_release(dev);
 
-               /* Done configuration */
+       if (err)
+               goto out;
 
-               if (imm_init(dev)) {
-                       imm_pb_release(dev);
-                       parport_unregister_device(dev->dev);
-                       continue;
-               }
-               imm_pb_release(dev);
+       /* now the glue ... */
+       switch (dev->mode) {
+       case IMM_NIBBLE:
+       case IMM_PS2:
+               ports = 3;
+               break;
+       case IMM_EPP_8:
+       case IMM_EPP_16:
+       case IMM_EPP_32:
+               ports = 8;
+               break;
+       default:        /* Never gets here */
+               BUG();
+       }
 
-               /* now the glue ... */
-               switch (dev->mode) {
-               case IMM_NIBBLE:
-                       ports = 3;
-                       break;
-               case IMM_PS2:
-                       ports = 3;
-                       break;
-               case IMM_EPP_8:
-               case IMM_EPP_16:
-               case IMM_EPP_32:
-                       ports = 8;
-                       break;
-               default:        /* Never gets here */
-                       continue;
-               }
+       INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
 
-               INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
+       err = -ENOMEM;
+       host = scsi_host_alloc(&imm_template, 0);
+       if (!host)
+               goto out;
+       list_add_tail(&host->sht_legacy_list, &imm_template.legacy_hosts);
+       host->io_port = pb->base;
+       host->n_io_port = ports;
+       host->dma_channel = -1;
+       host->unique_id = dev - imm_hosts;
+       err = scsi_add_host(host, NULL);
+       if (err)
+               goto out1;
+       scsi_scan_host(host);
+       return 0;
 
-               hreg = scsi_host_alloc(host, 0);
-               if (hreg == NULL)
-                       continue;
-               list_add_tail(&hreg->sht_legacy_list, &host->legacy_hosts);
-               hreg->io_port = pb->base;
-               hreg->n_io_port = ports;
-               hreg->dma_channel = -1;
-               hreg->unique_id = i;
-               nhosts++;
-       }
-       if (nhosts == 0) {
-               if (try_again == 1) {
-                       return 0;
-               }
-               try_again = 1;
-               goto retry_entry;
-       } else {
-               return 1;       /* return number of hosts detected */
-       }
+out1:
+       list_del(&host->sht_legacy_list);
+       scsi_host_put(host);
+out:
+       parport_unregister_device(dev->dev);
+       return err;
 }
 
 /* This is to give the imm driver a way to modify the timings (and other
@@ -700,7 +686,7 @@ static int imm_select(imm_struct *dev, int target)
 static int imm_init(imm_struct *dev)
 {
        if (imm_connect(dev, 0) != 1)
-               return 1;
+               return -EIO;
        imm_reset_pulse(dev->base);
        udelay(1000);   /* Delay to allow devices to settle */
        imm_disconnect(dev);
@@ -1165,9 +1151,8 @@ static int device_check(imm_struct *dev)
                                dev->mode = old_mode;
                                goto second_pass;
                        }
-                       printk
-                           ("imm: Unable to establish communication, aborting driver load.\n");
-                       return 1;
+                       printk("imm: Unable to establish communication\n");
+                       return -EIO;
                }
                w_ctr(ppb, 0x0c);
 
@@ -1192,8 +1177,8 @@ static int device_check(imm_struct *dev)
                                goto second_pass;
                        }
                        printk
-                           ("imm: Unable to establish communication, aborting driver load.\n");
-                       return 1;
+                           ("imm: Unable to establish communication\n");
+                       return -EIO;
                }
                imm_disconnect(dev);
                printk
@@ -1206,11 +1191,11 @@ static int device_check(imm_struct *dev)
                udelay(1000);
                return 0;
        }
-       printk("imm: No devices found, aborting driver load.\n");
-       return 1;
+       printk("imm: No devices found\n");
+       return -ENODEV;
 }
 
-static Scsi_Host_Template driver_template = {
+static Scsi_Host_Template imm_template = {
        .module                 = THIS_MODULE,
        .proc_name              = "imm",
        .proc_info              = imm_proc_info,
@@ -1229,34 +1214,24 @@ static Scsi_Host_Template driver_template = {
 
 static int __init imm_driver_init(void)
 {
-       struct scsi_host_template *sht = &driver_template;
-       struct Scsi_Host *shost;
-       struct list_head *l;
-       int error;
-
-       INIT_LIST_HEAD(&sht->legacy_hosts);
-
-       imm_detect(sht);
-       if (list_empty(&sht->legacy_hosts))
-               return -ENODEV;
-
-       list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
-               error = scsi_add_host(shost, NULL);
-               if (error)
-                       goto fail;
-               scsi_scan_host(shost);
+       struct parport *pb = parport_enumerate();
+       int i, nhosts;
+
+       INIT_LIST_HEAD(&imm_template.legacy_hosts);
+
+       printk("imm: Version %s\n", IMM_VERSION);
+
+       for (i = 0, nhosts = 0; pb; i++, pb = pb->next) {
+               imm_struct *dev = &imm_hosts[i];
+               if (imm_probe(dev, pb) == 0)
+                       nhosts++;
        }
-       return 0;
- fail:
-       l = &shost->sht_legacy_list;
-       while ((l = l->prev) != &sht->legacy_hosts)
-               scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list));
-       return error;
+       return nhosts ? 0 : -ENODEV;
 }
 
 static void __exit imm_driver_exit(void)
 {
-       struct scsi_host_template *sht = &driver_template;
+       struct scsi_host_template *sht = &imm_template;
        struct Scsi_Host *host, *s;
 
        list_for_each_entry(host, &sht->legacy_hosts, sht_legacy_list)