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,135 +85,108 @@ static inline void ppa_pb_release(ppa_struct *dev) ...@@ -95,135 +85,108 @@ 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; int modes, ppb, ppb_hi;
/*
* 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) { dev->base = -1;
printk("ppa: parport reports no devices.\n"); dev->mode = PPA_AUTODETECT;
return 0; dev->recon_tmo = PPA_RECON_TMO;
} dev->dev = parport_register_device(pb, "ppa", NULL, ppa_wakeup,
retry_entry:
for (i = 0; pb; i++, pb = pb->next) {
int modes, ppb, ppb_hi;
ppa_struct *dev = &ppa_hosts[i];
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 ]
*/ */
if (ppa_pb_claim(dev)) { err = -EBUSY;
unsigned long now = jiffies; if (ppa_pb_claim(dev)) {
while (dev->p_busy) { unsigned long now = jiffies;
schedule(); /* We are safe to schedule here */ while (dev->p_busy) {
if (time_after(jiffies, now + 3 * HZ)) { schedule(); /* We are safe to schedule here */
printk(KERN_ERR if (time_after(jiffies, now + 3 * HZ)) {
"ppa%d: failed to claim parport because a " printk(KERN_ERR
"pardevice is owning the port for too longtime!\n", "ppa%d: failed to claim parport because a "
i); "pardevice is owning the port for too longtime!\n",
parport_unregister_device(dev->dev); dev - ppa_hosts);
spin_lock_irq(dev->cur_cmd-> goto out;
device->host->host_lock);
return 0;
}
} }
} }
ppb = dev->base = dev->dev->port->base; }
ppb_hi = dev->dev->port->base_hi; ppb = dev->base = dev->dev->port->base;
w_ctr(ppb, 0x0c); ppb_hi = dev->dev->port->base_hi;
modes = dev->dev->port->modes; w_ctr(ppb, 0x0c);
modes = dev->dev->port->modes;
/* Mode detection works up the chain of speed /* Mode detection works up the chain of speed
* This avoids a nasty if-then-else-if-... tree * This avoids a nasty if-then-else-if-... tree
*/ */
dev->mode = PPA_NIBBLE; dev->mode = PPA_NIBBLE;
if (modes & PARPORT_MODE_TRISTATE) if (modes & PARPORT_MODE_TRISTATE)
dev->mode = PPA_PS2; dev->mode = PPA_PS2;
if (modes & PARPORT_MODE_ECP) { if (modes & PARPORT_MODE_ECP) {
w_ecr(ppb_hi, 0x20); w_ecr(ppb_hi, 0x20);
dev->mode = PPA_PS2; dev->mode = PPA_PS2;
} }
if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP)) if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP))
w_ecr(ppb_hi, 0x80); w_ecr(ppb_hi, 0x80);
/* Done configuration */ /* Done configuration */
if (ppa_init(dev)) { err = ppa_init(dev);
ppa_pb_release(dev); ppa_pb_release(dev);
parport_unregister_device(dev->dev);
continue;
}
ppa_pb_release(dev);
/* now the glue ... */
switch (dev->mode) {
case PPA_NIBBLE:
ports = 3;
break;
case PPA_PS2:
ports = 3;
break;
case PPA_EPP_8:
case PPA_EPP_16:
case PPA_EPP_32:
ports = 8;
break;
default: /* Never gets here */
continue;
}
INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev); if (err)
goto out;
hreg = scsi_host_alloc(host, 0); /* now the glue ... */
if (hreg == NULL) switch (dev->mode) {
continue; case PPA_NIBBLE:
list_add_tail(&hreg->sht_legacy_list, &host->legacy_hosts); ports = 3;
hreg->io_port = pb->base; break;
hreg->n_io_port = ports; case PPA_PS2:
hreg->dma_channel = -1; ports = 3;
hreg->unique_id = i; break;
dev->host = hreg->host_no; case PPA_EPP_8:
nhosts++; case PPA_EPP_16:
case PPA_EPP_32:
ports = 8;
break;
default: /* Never gets here */
BUG();
} }
if (nhosts == 0) {
if (try_again == 1) { INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev);
printk("WARNING - no ppa compatible devices found.\n");
printk err = -ENOMEM;
(" As of 31/Aug/1998 Iomega started shipping parallel\n"); host = scsi_host_alloc(&ppa_template, 0);
printk if (!host)
(" port ZIP drives with a different interface which is\n"); goto out;
printk list_add_tail(&host->sht_legacy_list, &ppa_template.legacy_hosts);
(" supported by the imm (ZIP Plus) driver. If the\n"); host->io_port = pb->base;
printk host->n_io_port = ports;
(" cable is marked with \"AutoDetect\", this is what has\n"); host->dma_channel = -1;
printk(" happened.\n"); host->unique_id = dev - ppa_hosts;
return 0; err = scsi_add_host(host, NULL);
} if (err)
try_again = 1; goto out1;
goto retry_entry; scsi_scan_host(host);
} else return 0;
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 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) return 0;
goto fail;
scsi_scan_host(shost);
} }
return 0;
fail: for (i = 0; pb; i++, pb = pb->next) {
l = &shost->sht_legacy_list; ppa_struct *dev = &ppa_hosts[i];
while ((l = l->prev) != &sht->legacy_hosts) if (ppa_probe(dev, pb))
scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list)); nhosts++;
return error; }
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