Commit 9234c5a2 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] scsi/imm.c cleanup and fixes (5/8)

	* 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().
parent f7d83e8b
...@@ -100,38 +100,25 @@ static inline void imm_pb_release(imm_struct *dev) ...@@ -100,38 +100,25 @@ static inline void imm_pb_release(imm_struct *dev)
* Parallel port probing routines * * 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 ports;
int i, nhosts, try_again;
struct parport *pb;
pb = parport_enumerate();
printk("imm: Version %s\n", IMM_VERSION);
nhosts = 0;
try_again = 0;
if (!pb) {
printk("imm: parport reports no devices.\n");
return 0;
}
retry_entry:
for (i = 0; pb; i++, pb = pb->next) {
imm_struct *dev = &imm_hosts[i];
int modes, ppb; int modes, ppb;
int err;
dev->dev = dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup,
parport_register_device(pb, "imm", NULL, imm_wakeup,
NULL, 0, dev); NULL, 0, dev);
if (!dev->dev) if (!dev->dev)
continue; return -ENOMEM;
/* Claim the bus so it remembers what we do to the control /* Claim the bus so it remembers what we do to the control
* registers. [ CTR and ECP ] * registers. [ CTR and ECP ]
*/ */
err = -EBUSY;
if (imm_pb_claim(dev)) { if (imm_pb_claim(dev)) {
unsigned long now = jiffies; unsigned long now = jiffies;
while (dev->p_busy) { while (dev->p_busy) {
...@@ -140,9 +127,8 @@ static int imm_detect(Scsi_Host_Template * host) ...@@ -140,9 +127,8 @@ static int imm_detect(Scsi_Host_Template * host)
printk(KERN_ERR printk(KERN_ERR
"imm%d: failed to claim parport because a " "imm%d: failed to claim parport because a "
"pardevice is owning the port for too longtime!\n", "pardevice is owning the port for too longtime!\n",
i); dev - imm_hosts);
parport_unregister_device(dev->dev); goto out;
return 0;
} }
} }
} }
...@@ -161,18 +147,16 @@ static int imm_detect(Scsi_Host_Template * host) ...@@ -161,18 +147,16 @@ static int imm_detect(Scsi_Host_Template * host)
/* Done configuration */ /* Done configuration */
if (imm_init(dev)) { err = imm_init(dev);
imm_pb_release(dev);
parport_unregister_device(dev->dev);
continue;
}
imm_pb_release(dev); imm_pb_release(dev);
if (err)
goto out;
/* now the glue ... */ /* now the glue ... */
switch (dev->mode) { switch (dev->mode) {
case IMM_NIBBLE: case IMM_NIBBLE:
ports = 3;
break;
case IMM_PS2: case IMM_PS2:
ports = 3; ports = 3;
break; break;
...@@ -182,30 +166,32 @@ static int imm_detect(Scsi_Host_Template * host) ...@@ -182,30 +166,32 @@ static int imm_detect(Scsi_Host_Template * host)
ports = 8; ports = 8;
break; break;
default: /* Never gets here */ default: /* Never gets here */
continue; BUG();
} }
INIT_WORK(&dev->imm_tq, imm_interrupt, dev); INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
hreg = scsi_host_alloc(host, 0); err = -ENOMEM;
if (hreg == NULL) host = scsi_host_alloc(&imm_template, 0);
continue; if (!host)
list_add_tail(&hreg->sht_legacy_list, &host->legacy_hosts); goto out;
hreg->io_port = pb->base; list_add_tail(&host->sht_legacy_list, &imm_template.legacy_hosts);
hreg->n_io_port = ports; host->io_port = pb->base;
hreg->dma_channel = -1; host->n_io_port = ports;
hreg->unique_id = i; host->dma_channel = -1;
nhosts++; host->unique_id = dev - imm_hosts;
} err = scsi_add_host(host, NULL);
if (nhosts == 0) { if (err)
if (try_again == 1) { goto out1;
scsi_scan_host(host);
return 0; return 0;
}
try_again = 1; out1:
goto retry_entry; list_del(&host->sht_legacy_list);
} else { scsi_host_put(host);
return 1; /* return number of hosts detected */ out:
} parport_unregister_device(dev->dev);
return err;
} }
/* This is to give the imm driver a way to modify the timings (and other /* 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) ...@@ -700,7 +686,7 @@ static int imm_select(imm_struct *dev, int target)
static int imm_init(imm_struct *dev) static int imm_init(imm_struct *dev)
{ {
if (imm_connect(dev, 0) != 1) if (imm_connect(dev, 0) != 1)
return 1; return -EIO;
imm_reset_pulse(dev->base); imm_reset_pulse(dev->base);
udelay(1000); /* Delay to allow devices to settle */ udelay(1000); /* Delay to allow devices to settle */
imm_disconnect(dev); imm_disconnect(dev);
...@@ -1165,9 +1151,8 @@ static int device_check(imm_struct *dev) ...@@ -1165,9 +1151,8 @@ static int device_check(imm_struct *dev)
dev->mode = old_mode; dev->mode = old_mode;
goto second_pass; goto second_pass;
} }
printk printk("imm: Unable to establish communication\n");
("imm: Unable to establish communication, aborting driver load.\n"); return -EIO;
return 1;
} }
w_ctr(ppb, 0x0c); w_ctr(ppb, 0x0c);
...@@ -1192,8 +1177,8 @@ static int device_check(imm_struct *dev) ...@@ -1192,8 +1177,8 @@ static int device_check(imm_struct *dev)
goto second_pass; goto second_pass;
} }
printk printk
("imm: Unable to establish communication, aborting driver load.\n"); ("imm: Unable to establish communication\n");
return 1; return -EIO;
} }
imm_disconnect(dev); imm_disconnect(dev);
printk printk
...@@ -1206,11 +1191,11 @@ static int device_check(imm_struct *dev) ...@@ -1206,11 +1191,11 @@ static int device_check(imm_struct *dev)
udelay(1000); udelay(1000);
return 0; return 0;
} }
printk("imm: No devices found, aborting driver load.\n"); printk("imm: No devices found\n");
return 1; return -ENODEV;
} }
static Scsi_Host_Template driver_template = { static Scsi_Host_Template imm_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.proc_name = "imm", .proc_name = "imm",
.proc_info = imm_proc_info, .proc_info = imm_proc_info,
...@@ -1229,34 +1214,24 @@ static Scsi_Host_Template driver_template = { ...@@ -1229,34 +1214,24 @@ static Scsi_Host_Template driver_template = {
static int __init imm_driver_init(void) static int __init imm_driver_init(void)
{ {
struct scsi_host_template *sht = &driver_template; struct parport *pb = parport_enumerate();
struct Scsi_Host *shost; int i, nhosts;
struct list_head *l;
int error;
INIT_LIST_HEAD(&sht->legacy_hosts); INIT_LIST_HEAD(&imm_template.legacy_hosts);
imm_detect(sht); printk("imm: Version %s\n", IMM_VERSION);
if (list_empty(&sht->legacy_hosts))
return -ENODEV;
list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { for (i = 0, nhosts = 0; pb; i++, pb = pb->next) {
error = scsi_add_host(shost, NULL); imm_struct *dev = &imm_hosts[i];
if (error) if (imm_probe(dev, pb) == 0)
goto fail; nhosts++;
scsi_scan_host(shost);
} }
return 0; return nhosts ? 0 : -ENODEV;
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;
} }
static void __exit imm_driver_exit(void) 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; struct Scsi_Host *host, *s;
list_for_each_entry(host, &sht->legacy_hosts, sht_legacy_list) list_for_each_entry(host, &sht->legacy_hosts, sht_legacy_list)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment