Commit ec1807db authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] scsi/ppa.c cleanup and fixes (5/9)

	* starting to kill ppa_detect - we move the "probe a single port"
logics into a separate function and shift scanning into ppa_driver_init().
Later that will give us a parport_driver ->attach().
parent ee536cd9
...@@ -26,7 +26,6 @@ typedef struct { ...@@ -26,7 +26,6 @@ typedef struct {
struct pardevice *dev; /* Parport device entry */ struct pardevice *dev; /* Parport device entry */
int base; /* Actual port address */ int base; /* Actual port address */
int mode; /* Transfer mode */ int mode; /* Transfer mode */
int host; /* Host number (for proc) */
Scsi_Cmnd *cur_cmd; /* Current queued command */ Scsi_Cmnd *cur_cmd; /* Current queued command */
struct work_struct ppa_tq; /* Polling interrupt stuff */ struct work_struct ppa_tq; /* Polling interrupt stuff */
unsigned long jstart; /* Jiffies at start */ unsigned long jstart; /* Jiffies at start */
...@@ -35,19 +34,10 @@ typedef struct { ...@@ -35,19 +34,10 @@ typedef struct {
unsigned int p_busy:1; /* Parport sharing busy flag */ unsigned int p_busy:1; /* Parport sharing busy flag */
} ppa_struct; } ppa_struct;
#define PPA_EMPTY \
{ .base = -1, \
.mode = PPA_AUTODETECT, \
.host = -1, \
.ppa_tq = { .func = ppa_interrupt }, \
.recon_tmo = PPA_RECON_TMO, \
}
#include "ppa.h" #include "ppa.h"
#define NO_HOSTS 4 #define NO_HOSTS 4
static ppa_struct ppa_hosts[NO_HOSTS] = static ppa_struct ppa_hosts[NO_HOSTS];
{ PPA_EMPTY, PPA_EMPTY, PPA_EMPTY, PPA_EMPTY };
static inline ppa_struct *ppa_dev(struct Scsi_Host *host) static inline ppa_struct *ppa_dev(struct Scsi_Host *host)
{ {
...@@ -95,43 +85,28 @@ static inline void ppa_pb_release(ppa_struct *dev) ...@@ -95,43 +85,28 @@ static inline void ppa_pb_release(ppa_struct *dev)
/* /*
* Start of Chipset kludges * Start of Chipset kludges
*/ */
static Scsi_Host_Template ppa_template;
static int ppa_detect(Scsi_Host_Template *host) static int ppa_probe(ppa_struct *dev, struct parport *pb)
{ {
struct Scsi_Host *hreg = NULL; struct Scsi_Host *host;
int ports; int ports;
int i, nhosts, try_again; int err;
struct parport *pb;
/*
* unlock to allow the lowlevel parport driver to probe
* the irqs
*/
pb = parport_enumerate();
printk("ppa: Version %s\n", PPA_VERSION);
nhosts = 0;
try_again = 0;
if (!pb) {
printk("ppa: parport reports no devices.\n");
return 0;
}
retry_entry:
for (i = 0; pb; i++, pb = pb->next) {
int modes, ppb, ppb_hi; int modes, ppb, ppb_hi;
ppa_struct *dev = &ppa_hosts[i];
dev->dev = dev->base = -1;
parport_register_device(pb, "ppa", NULL, ppa_wakeup, dev->mode = PPA_AUTODETECT;
dev->recon_tmo = PPA_RECON_TMO;
dev->dev = parport_register_device(pb, "ppa", NULL, ppa_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 (ppa_pb_claim(dev)) { if (ppa_pb_claim(dev)) {
unsigned long now = jiffies; unsigned long now = jiffies;
while (dev->p_busy) { while (dev->p_busy) {
...@@ -140,11 +115,8 @@ static int ppa_detect(Scsi_Host_Template *host) ...@@ -140,11 +115,8 @@ static int ppa_detect(Scsi_Host_Template *host)
printk(KERN_ERR printk(KERN_ERR
"ppa%d: failed to claim parport because a " "ppa%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 - ppa_hosts);
parport_unregister_device(dev->dev); goto out;
spin_lock_irq(dev->cur_cmd->
device->host->host_lock);
return 0;
} }
} }
} }
...@@ -170,12 +142,12 @@ static int ppa_detect(Scsi_Host_Template *host) ...@@ -170,12 +142,12 @@ static int ppa_detect(Scsi_Host_Template *host)
/* Done configuration */ /* Done configuration */
if (ppa_init(dev)) { err = ppa_init(dev);
ppa_pb_release(dev);
parport_unregister_device(dev->dev);
continue;
}
ppa_pb_release(dev); ppa_pb_release(dev);
if (err)
goto out;
/* now the glue ... */ /* now the glue ... */
switch (dev->mode) { switch (dev->mode) {
case PPA_NIBBLE: case PPA_NIBBLE:
...@@ -190,40 +162,31 @@ static int ppa_detect(Scsi_Host_Template *host) ...@@ -190,40 +162,31 @@ static int ppa_detect(Scsi_Host_Template *host)
ports = 8; ports = 8;
break; break;
default: /* Never gets here */ default: /* Never gets here */
continue; BUG();
} }
INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev); INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev);
hreg = scsi_host_alloc(host, 0); err = -ENOMEM;
if (hreg == NULL) host = scsi_host_alloc(&ppa_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, &ppa_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;
dev->host = hreg->host_no; host->unique_id = dev - ppa_hosts;
nhosts++; err = scsi_add_host(host, NULL);
} if (err)
if (nhosts == 0) { goto out1;
if (try_again == 1) { scsi_scan_host(host);
printk("WARNING - no ppa compatible devices found.\n");
printk
(" As of 31/Aug/1998 Iomega started shipping parallel\n");
printk
(" port ZIP drives with a different interface which is\n");
printk
(" supported by the imm (ZIP Plus) driver. If the\n");
printk
(" cable is marked with \"AutoDetect\", this is what has\n");
printk(" happened.\n");
return 0; return 0;
} out1:
try_again = 1; list_del(&host->sht_legacy_list);
goto retry_entry; scsi_host_put(host);
} else out:
return 1; /* return number of hosts detected */ parport_unregister_device(dev->dev);
return err;
} }
/* This is to give the ppa driver a way to modify the timings (and other /* This is to give the ppa driver a way to modify the timings (and other
...@@ -616,10 +579,10 @@ static int ppa_init(ppa_struct *dev) ...@@ -616,10 +579,10 @@ static int ppa_init(ppa_struct *dev)
ppa_disconnect(dev); ppa_disconnect(dev);
udelay(1000); /* Another delay to allow devices to settle */ udelay(1000); /* Another delay to allow devices to settle */
if (!retv) if (retv)
retv = device_check(dev); return -EIO;
return retv; return device_check(dev);
} }
static inline int ppa_send_command(Scsi_Cmnd *cmd) static inline int ppa_send_command(Scsi_Cmnd *cmd)
...@@ -1061,9 +1024,7 @@ static int device_check(ppa_struct *dev) ...@@ -1061,9 +1024,7 @@ static int device_check(ppa_struct *dev)
dev->mode = old_mode; dev->mode = old_mode;
goto second_pass; goto second_pass;
} }
printk return -EIO;
("ppa: Unable to establish communication, aborting driver load.\n");
return 1;
} }
w_ctr(ppb, 0x0c); w_ctr(ppb, 0x0c);
k = 1000000; /* 1 Second */ k = 1000000; /* 1 Second */
...@@ -1086,9 +1047,7 @@ static int device_check(ppa_struct *dev) ...@@ -1086,9 +1047,7 @@ static int device_check(ppa_struct *dev)
dev->mode = old_mode; dev->mode = old_mode;
goto second_pass; goto second_pass;
} }
printk return -EIO;
("ppa: Unable to establish communication, aborting driver load.\n");
return 1;
} }
ppa_disconnect(dev); ppa_disconnect(dev);
printk("ppa: Communication established with ID %i using %s\n", printk("ppa: Communication established with ID %i using %s\n",
...@@ -1100,8 +1059,7 @@ static int device_check(ppa_struct *dev) ...@@ -1100,8 +1059,7 @@ static int device_check(ppa_struct *dev)
udelay(1000); udelay(1000);
return 0; return 0;
} }
printk("ppa: No devices found, aborting driver load.\n"); return -ENODEV;
return 1;
} }
static Scsi_Host_Template ppa_template = { static Scsi_Host_Template ppa_template = {
...@@ -1123,29 +1081,26 @@ static Scsi_Host_Template ppa_template = { ...@@ -1123,29 +1081,26 @@ static Scsi_Host_Template ppa_template = {
static int __init ppa_driver_init(void) static int __init ppa_driver_init(void)
{ {
struct scsi_host_template *sht = &ppa_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(&ppa_template.legacy_hosts);
ppa_detect(sht); printk("ppa: Version %s\n", PPA_VERSION);
if (list_empty(&sht->legacy_hosts)) nhosts = 0;
return -ENODEV;
list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { if (!pb) {
error = scsi_add_host(shost, NULL); printk("ppa: parport reports no devices.\n");
if (error)
goto fail;
scsi_scan_host(shost);
}
return 0; return 0;
fail: }
l = &shost->sht_legacy_list;
while ((l = l->prev) != &sht->legacy_hosts) for (i = 0; pb; i++, pb = pb->next) {
scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list)); ppa_struct *dev = &ppa_hosts[i];
return error; if (ppa_probe(dev, pb))
nhosts++;
}
return nhosts ? 0 : -ENODEV;
} }
static void __exit ppa_driver_exit(void) static void __exit ppa_driver_exit(void)
......
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