aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-12 16:54:43 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-12 16:54:43 -0400
commita890b15c0990cc8d686edcc85f5fccde71ad5ce9 (patch)
tree73162355b58283a2531f13fbbf663809f95c1483 /drivers/scsi
parent79fa1b677be3a985cc66b9218a4dd09818f1051b (diff)
parent26ec634c31a11a003040e10b4d650495158632fd (diff)
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/3w-xxxx.c3
-rw-r--r--drivers/scsi/ahci.c45
-rw-r--r--drivers/scsi/ata_piix.c1
-rw-r--r--drivers/scsi/hosts.c12
-rw-r--r--drivers/scsi/libata-core.c126
-rw-r--r--drivers/scsi/libata-eh.c7
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/libata.h7
-rw-r--r--drivers/scsi/pdc_adma.c1
-rw-r--r--drivers/scsi/sata_mv.c1
-rw-r--r--drivers/scsi/sata_nv.c1
-rw-r--r--drivers/scsi/sata_promise.c1
-rw-r--r--drivers/scsi/sata_qstor.c1
-rw-r--r--drivers/scsi/sata_sil.c1
-rw-r--r--drivers/scsi/sata_sil24.c246
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c3
-rw-r--r--drivers/scsi/sata_sx4.c1
-rw-r--r--drivers/scsi/sata_uli.c1
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c1
-rw-r--r--drivers/scsi/scsi_error.c4
22 files changed, 276 insertions, 198 deletions
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 25f678d0780..e8e41e6eb42 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1508,10 +1508,12 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
struct scsi_cmnd *cmd = tw_dev->srb[request_id];
void *buf;
unsigned int transfer_len;
+ unsigned long flags = 0;
if (cmd->use_sg) {
struct scatterlist *sg =
(struct scatterlist *)cmd->request_buffer;
+ local_irq_save(flags);
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
transfer_len = min(sg->length, len);
} else {
@@ -1526,6 +1528,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
sg = (struct scatterlist *)cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ local_irq_restore(flags);
}
}
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index ff48066d4c4..1b8429cb3c9 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = AHCI_MAX_SG,
@@ -517,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
}
-static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val,
- unsigned long interval_msec,
- unsigned long timeout_msec)
-{
- unsigned long timeout;
- u32 tmp;
-
- timeout = jiffies + (timeout_msec * HZ) / 1000;
- do {
- tmp = readl(reg);
- if ((tmp & mask) == val)
- return 0;
- msleep(interval_msec);
- } while (time_before(jiffies, timeout));
-
- return -1;
-}
-
-static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp = ap->private_data;
@@ -544,6 +525,7 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
struct ata_taskfile tf;
+ u32 tmp;
u8 *fis;
int rc;
@@ -565,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
/* check BUSY/DRQ, perform Command List Override if necessary */
ahci_tf_read(ap, &tf);
if (tf.command & (ATA_BUSY | ATA_DRQ)) {
- u32 tmp;
-
if (!(hpriv->cap & HOST_CAP_CLO)) {
rc = -EIO;
reason = "port busy but no CLO";
@@ -576,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_CLO;
writel(tmp, port_mmio + PORT_CMD);
- readl(port_mmio + PORT_CMD); /* flush */
- if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0,
- 1, 500)) {
+ tmp = ata_wait_register(port_mmio + PORT_CMD,
+ PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
+ if (tmp & PORT_CMD_CLO) {
rc = -EIO;
reason = "CLO failed";
goto fail_restart;
@@ -600,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
writel(1, port_mmio + PORT_CMD_ISSUE);
- readl(port_mmio + PORT_CMD_ISSUE); /* flush */
- if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) {
+ tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
+ if (tmp & 0x1) {
rc = -EIO;
reason = "1st FIS failed";
goto fail;
@@ -647,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
fail_restart:
ahci_start_engine(ap);
fail:
- if (verbose)
- printk(KERN_ERR "ata%u: softreset failed (%s)\n",
- ap->id, reason);
- else
- DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason);
+ printk(KERN_ERR "ata%u: softreset failed (%s)\n",
+ ap->id, reason);
return rc;
}
-static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
{
int rc;
DPRINTK("ENTER\n");
ahci_stop_engine(ap);
- rc = sata_std_hardreset(ap, verbose, class);
+ rc = sata_std_hardreset(ap, class);
ahci_start_engine(ap);
if (rc == 0)
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 83839706f5e..62dabf74188 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -209,7 +209,6 @@ static struct scsi_host_template piix_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index ef57f253031..dfcb96f3e60 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -294,18 +294,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
if (sht->unchecked_isa_dma && privsize)
gfp_mask |= __GFP_DMA;
- /* Check to see if this host has any error handling facilities */
- if (!sht->eh_strategy_handler && !sht->eh_abort_handler &&
- !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler &&
- !sht->eh_host_reset_handler) {
- printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n"
- "ERROR: This is not a safe way to run your "
- "SCSI host\n"
- "ERROR: The error handling must be added to "
- "this driver\n", sht->proc_name);
- dump_stack();
- }
-
shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
if (!shost)
return NULL;
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 2b2feb6462a..5d38a6cc573 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1425,12 +1425,9 @@ static int ata_bus_probe(struct ata_port *ap)
/* read IDENTIFY page and configure devices */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->device[i];
- dev->class = classes[i];
- if (!tries[i]) {
- ata_down_xfermask_limit(ap, dev, 1);
- ata_dev_disable(ap, dev);
- }
+ if (tries[i])
+ dev->class = classes[i];
if (!ata_dev_enabled(dev))
continue;
@@ -1458,12 +1455,12 @@ static int ata_bus_probe(struct ata_port *ap)
break;
}
rc = 0;
- } else {
+ } else
rc = ata_set_mode(ap, &dev);
- if (rc) {
- down_xfermask = 1;
- goto fail;
- }
+
+ if (rc) {
+ down_xfermask = 1;
+ goto fail;
}
for (i = 0; i < ATA_MAX_DEVICES; i++)
@@ -1491,6 +1488,11 @@ static int ata_bus_probe(struct ata_port *ap)
tries[dev->devno] = 0;
}
+ if (!tries[dev->devno]) {
+ ata_down_xfermask_limit(ap, dev, 1);
+ ata_dev_disable(ap, dev);
+ }
+
goto retry;
}
@@ -1750,7 +1752,7 @@ int ata_set_sata_spd_needed(struct ata_port *ap)
* 0 if spd doesn't need to be changed, 1 if spd has been
* changed. -EOPNOTSUPP if SCR registers are inaccessible.
*/
-static int ata_set_sata_spd(struct ata_port *ap)
+int ata_set_sata_spd(struct ata_port *ap)
{
u32 scontrol;
@@ -2246,8 +2248,10 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
* the bus shows 0xFF because the odd clown forgets the D7
* pulldown resistor.
*/
- if (ata_check_status(ap) == 0xFF)
+ if (ata_check_status(ap) == 0xFF) {
+ printk(KERN_ERR "ata%u: SRST failed (status 0xFF)\n", ap->id);
return AC_ERR_OTHER;
+ }
ata_bus_post_reset(ap, devmask);
@@ -2383,12 +2387,16 @@ void ata_std_probeinit(struct ata_port *ap)
if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
u32 spd;
+ /* set cable type and resume link */
+ ap->cbl = ATA_CBL_SATA;
sata_phy_resume(ap);
+ /* init sata_spd_limit to the current value */
spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
if (spd)
ap->sata_spd_limit &= (1 << spd) - 1;
+ /* wait for device */
if (sata_dev_present(ap))
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
}
@@ -2397,7 +2405,6 @@ void ata_std_probeinit(struct ata_port *ap)
/**
* ata_std_softreset - reset host port via ATA SRST
* @ap: port to reset
- * @verbose: fail verbosely
* @classes: resulting classes of attached devices
*
* Reset host port using ATA SRST. This function is to be used
@@ -2409,7 +2416,7 @@ void ata_std_probeinit(struct ata_port *ap)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
{
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
@@ -2435,12 +2442,8 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
DPRINTK("about to softreset, devmask=%x\n", devmask);
err_mask = ata_bus_softreset(ap, devmask);
if (err_mask) {
- if (verbose)
- printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
- ap->id, err_mask);
- else
- DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
- err_mask);
+ printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+ ap->id, err_mask);
return -EIO;
}
@@ -2457,7 +2460,6 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
/**
* sata_std_hardreset - reset host port via SATA phy reset
* @ap: port to reset
- * @verbose: fail verbosely
* @class: resulting class of attached device
*
* SATA phy-reset host port using DET bits of SControl register.
@@ -2470,7 +2472,7 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
{
u32 scontrol;
@@ -2510,11 +2512,8 @@ int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
}
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
- if (verbose)
- printk(KERN_ERR "ata%u: COMRESET failed "
- "(device not ready)\n", ap->id);
- else
- DPRINTK("EXIT, device not ready\n");
+ printk(KERN_ERR
+ "ata%u: COMRESET failed (device not ready)\n", ap->id);
return -EIO;
}
@@ -2545,10 +2544,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
{
DPRINTK("ENTER\n");
- /* set cable type if it isn't already set */
- if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
- ap->cbl = ATA_CBL_SATA;
-
/* print link status */
if (ap->cbl == ATA_CBL_SATA)
sata_print_link_status(ap);
@@ -2598,7 +2593,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
ata_reset_fn_t hardreset;
hardreset = NULL;
- if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+ if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read)
hardreset = sata_std_hardreset;
return ata_drive_probe_reset(ap, ata_std_probeinit,
@@ -2606,16 +2601,15 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
ata_std_postreset, classes);
}
-int ata_do_reset(struct ata_port *ap,
- ata_reset_fn_t reset, ata_postreset_fn_t postreset,
- int verbose, unsigned int *classes)
+int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+ ata_postreset_fn_t postreset, unsigned int *classes)
{
int i, rc;
for (i = 0; i < ATA_MAX_DEVICES; i++)
classes[i] = ATA_DEV_UNKNOWN;
- rc = reset(ap, verbose, classes);
+ rc = reset(ap, classes);
if (rc)
return rc;
@@ -2659,8 +2653,6 @@ int ata_do_reset(struct ata_port *ap,
* - If classification is supported, fill classes[] with
* recognized class codes.
* - If classification is not supported, leave classes[] alone.
- * - If verbose is non-zero, print error message on failure;
- * otherwise, shut up.
*
* LOCKING:
* Kernel thread context (may sleep)
@@ -2680,7 +2672,7 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
probeinit(ap);
if (softreset && !ata_set_sata_spd_needed(ap)) {
- rc = ata_do_reset(ap, softreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, softreset, postreset, classes);
if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN)
goto done;
printk(KERN_INFO "ata%u: softreset failed, will try "
@@ -2692,7 +2684,7 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
goto done;
while (1) {
- rc = ata_do_reset(ap, hardreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, hardreset, postreset, classes);
if (rc == 0) {
if (classes[0] != ATA_DEV_UNKNOWN)
goto done;
@@ -2713,7 +2705,7 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
ap->id);
ssleep(5);
- rc = ata_do_reset(ap, softreset, postreset, 0, classes);
+ rc = ata_do_reset(ap, softreset, postreset, classes);
}
done:
@@ -4846,7 +4838,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
host->transportt = &ata_scsi_transport_template;
- ap = (struct ata_port *) &host->hostdata[0];
+ ap = ata_shost_to_port(host);
ata_host_init(ap, host, host_set, ent, port_no);
@@ -5059,7 +5051,7 @@ void ata_host_set_remove(struct ata_host_set *host_set)
int ata_scsi_release(struct Scsi_Host *host)
{
- struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(host);
int i;
DPRINTK("ENTER\n");
@@ -5226,6 +5218,52 @@ int ata_ratelimit(void)
return rc;
}
+/**
+ * ata_wait_register - wait until register value changes
+ * @reg: IO-mapped register
+ * @mask: Mask to apply to read register value
+ * @val: Wait condition
+ * @interval_msec: polling interval in milliseconds
+ * @timeout_msec: timeout in milliseconds
+ *
+ * Waiting for some bits of register to change is a common
+ * operation for ATA controllers. This function reads 32bit LE
+ * IO-mapped register @reg and tests for the following condition.
+ *
+ * (*@reg & mask) != val
+ *
+ * If the condition is met, it returns; otherwise, the process is
+ * repeated after @interval_msec until timeout.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * The final register value.
+ */
+u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
+ unsigned long interval_msec,
+ unsigned long timeout_msec)
+{
+ unsigned long timeout;
+ u32 tmp;
+
+ tmp = ioread32(reg);
+
+ /* Calculate timeout _after_ the first read to make sure
+ * preceding writes reach the controller before starting to
+ * eat away the timeout.
+ */
+ timeout = jiffies + (timeout_msec * HZ) / 1000;
+
+ while ((tmp & mask) == val && time_before(jiffies, timeout)) {
+ msleep(interval_msec);
+ tmp = ioread32(reg);
+ }
+
+ return tmp;
+}
+
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
@@ -5262,6 +5300,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
EXPORT_SYMBOL_GPL(ata_bmdma_status);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
EXPORT_SYMBOL_GPL(ata_port_probe);
+EXPORT_SYMBOL_GPL(ata_set_sata_spd);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
@@ -5276,6 +5315,7 @@ EXPORT_SYMBOL_GPL(ata_dev_classify);
EXPORT_SYMBOL_GPL(ata_dev_pair);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
+EXPORT_SYMBOL_GPL(ata_wait_register);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 9a8eea11b0b..16db6221171 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -64,7 +64,7 @@
enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
{
struct Scsi_Host *host = cmd->device->host;
- struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(host);
unsigned long flags;
struct ata_queued_cmd *qc;
enum scsi_eh_timer_return ret = EH_HANDLED;
@@ -97,9 +97,9 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
* RETURNS:
* Zero.
*/
-int ata_scsi_error(struct Scsi_Host *host)
+void ata_scsi_error(struct Scsi_Host *host)
{
- struct ata_port *ap = (struct ata_port *)&host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(host);
DPRINTK("ENTER\n");
@@ -116,7 +116,6 @@ int ata_scsi_error(struct Scsi_Host *host)
scsi_eh_flush_done_q(&ap->eh_done_q);
DPRINTK("EXIT\n");
- return 0;
}
/**
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index c9c00149029..9871f8272df 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -98,6 +98,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
* It just needs the eh_timed_out hook.
*/
struct scsi_transport_template ata_scsi_transport_template = {
+ .eh_strategy_handler = ata_scsi_error,
.eh_timed_out = ata_scsi_timed_out,
};
@@ -394,7 +395,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
int ata_scsi_device_resume(struct scsi_device *sdev)
{
- struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = &ap->device[sdev->id];
return ata_device_resume(ap, dev);
@@ -402,7 +403,7 @@ int ata_scsi_device_resume(struct scsi_device *sdev)
int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state)
{
- struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = &ap->device[sdev->id];
return ata_device_suspend(ap, dev, state);
@@ -703,7 +704,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
struct ata_port *ap;
struct ata_device *dev;
- ap = (struct ata_port *) &sdev->host->hostdata[0];
+ ap = ata_shost_to_port(sdev->host);
dev = &ap->device[sdev->id];
ata_scsi_dev_config(sdev, dev);
@@ -2477,7 +2478,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
struct scsi_device *scsidev = cmd->device;
struct Scsi_Host *shost = scsidev->host;
- ap = (struct ata_port *) &shost->hostdata[0];
+ ap = ata_shost_to_port(shost);
spin_unlock(shost->host_lock);
spin_lock(&ap->host_set->lock);
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 652c08e3808..3f8b0a86378 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -56,10 +56,8 @@ extern int ata_set_sata_spd_needed(struct ata_port *ap);
extern int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
int force_pio0);
extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
-extern int ata_do_reset(struct ata_port *ap,
- ata_reset_fn_t reset,
- ata_postreset_fn_t postreset,
- int verbose, unsigned int *classes);
+extern int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+ ata_postreset_fn_t postreset, unsigned int *classes);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
@@ -105,5 +103,6 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
/* libata-eh.c */
extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
+extern void ata_scsi_error(struct Scsi_Host *host);
#endif /* __LIBATA_H__ */
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 1fca6f1afa9..a341fa8d329 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -143,7 +143,6 @@ static struct scsi_host_template adma_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index fd9f2173f06..08665ea1e94 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -378,7 +378,6 @@ static struct scsi_host_template mv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = MV_MAX_SG_CT / 2,
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 3a0004c3c8b..70c51088d37 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -201,7 +201,6 @@ static struct scsi_host_template nv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 03c647cbfb5..aaf896a0c63 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -112,7 +112,6 @@ static struct scsi_host_template pdc_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 1b7a9316810..54283e06070 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -132,7 +132,6 @@ static struct scsi_host_template qs_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = QS_MAX_PRD,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index f29c3e733a0..c9333577330 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -146,7 +146,6 @@ static struct scsi_host_template sil_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 646756abb10..e9fd869140c 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -86,6 +86,13 @@ enum {
/* HOST_SLOT_STAT bits */
HOST_SSTAT_ATTN = (1 << 31),
+ /* HOST_CTRL bits */
+ HOST_CTRL_M66EN = (1 << 16), /* M66EN PCI bus signal */
+ HOST_CTRL_TRDY = (1 << 17), /* latched PCI TRDY */
+ HOST_CTRL_STOP = (1 << 18), /* latched PCI STOP */
+ HOST_CTRL_DEVSEL = (1 << 19), /* latched PCI DEVSEL */
+ HOST_CTRL_REQ64 = (1 << 20), /* latched PCI REQ64 */
+
/*
* Port registers
* (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
@@ -142,8 +149,12 @@ enum {
PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */
PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */
PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */
- PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */
- PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */
+ PORT_IRQ_UNK_FIS = (1 << 6), /* unknown FIS received */
+ PORT_IRQ_DEV_XCHG = (1 << 7), /* device exchanged */
+ PORT_IRQ_8B10B = (1 << 8), /* 8b/10b decode error threshold */
+ PORT_IRQ_CRC = (1 << 9), /* CRC error threshold */
+ PORT_IRQ_HANDSHAKE = (1 << 10), /* handshake error threshold */
+ PORT_IRQ_SDB_NOTIFY = (1 << 11), /* SDB notify received */
/* bits[27:16] are unmasked (raw) */
PORT_IRQ_RAW_SHIFT = 16,
@@ -174,7 +185,7 @@ enum {
PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */
PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */
- PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */
+ PORT_CERR_XFR_MSTABRT = 34, /* PSD ecode 10 - master abort */
PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */
PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */
@@ -207,6 +218,11 @@ enum {
BID_SIL3132 = 1,
BID_SIL3131 = 2,
+ /* host flags */
+ SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
+ SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
+
IRQ_STAT_4PORTS = 0xf,
};
@@ -281,7 +297,6 @@ static struct scsi_host_template sil24_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
@@ -334,9 +349,8 @@ static struct ata_port_info sil24_port_info[] = {
/* sil_3124 */
{
.sht = &sil24_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- SIL24_NPORTS2FLAG(4),
+ .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
+ SIL24_FLAG_PCIX_IRQ_WOC,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -345,9 +359,7 @@ static struct ata_port_info sil24_port_info[] = {
/* sil_3132 */
{
.sht = &sil24_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- SIL24_NPORTS2FLAG(2),
+ .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -356,9 +368,7 @@ static struct ata_port_info sil24_port_info[] = {
/* sil_3131/sil_3531 */
{
.sht = &sil24_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- SIL24_NPORTS2FLAG(1),
+ .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -427,15 +437,30 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
*tf = pp->tf;
}
-static int sil24_softreset(struct ata_port *ap, int verbose,
- unsigned int *class)
+static int sil24_init_port(struct ata_port *ap)
+{
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ u32 tmp;
+
+ writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+ ata_wait_register(port + PORT_CTRL_STAT,
+ PORT_CS_INIT, PORT_CS_INIT, 10, 100);
+ tmp = ata_wait_register(port + PORT_CTRL_STAT,
+ PORT_CS_RDY, 0, 10, 100);
+
+ if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
+ return -EIO;
+ return 0;
+}
+
+static int sil24_softreset(struct ata_port *ap, unsigned int *class)
{
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
dma_addr_t paddr = pp->cmd_block_dma;
- unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ;
- u32 irq_enable, irq_stat;
+ u32 mask, irq_enable, irq_stat;
+ const char *reason;
DPRINTK("ENTER\n");
@@ -449,34 +474,35 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
- /*
- * XXX: Not sure whether the following sleep is needed or not.
- * The original driver had it. So....
- */
- msleep(10);
+ /* put the port into known state */
+ if (sil24_init_port(ap)) {
+ reason ="port not ready";
+ goto err;
+ }
- prb->ctrl = PRB_CTRL_SRST;
+ /* do SRST */
+ prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
prb->fis[1] = 0; /* no PM yet */
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+ writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
- do {
- irq_stat = readl(port + PORT_IRQ_STAT);
- writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
-
- irq_stat >>= PORT_IRQ_RAW_SHIFT;
- if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
- break;
+ mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
+ irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0,
+ 100, ATA_TMOUT_BOOT / HZ * 1000);
- msleep(100);
- } while (time_before(jiffies, timeout));
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */
+ irq_stat >>= PORT_IRQ_RAW_SHIFT;
/* restore IRQs */
writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
if (!(irq_stat & PORT_IRQ_COMPLETE)) {
- DPRINTK("EXIT, srst failed\n");
- return -EIO;
+ if (irq_stat & PORT_IRQ_ERROR)
+ reason = "SRST command error";
+ else
+ reason = "timeout";
+ goto err;
}
sil24_update_tf(ap);
@@ -488,15 +514,55 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
out:
DPRINTK("EXIT, class=%u\n", *class);
return 0;
+
+ err:
+ printk(KERN_ERR "ata%u: softreset failed (%s)\n", ap->id, reason);
+ return -EIO;
}
-static int sil24_hardreset(struct ata_port *ap, int verbose,
- unsigned int *class)
+static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
{
- unsigned int dummy_class;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ const char *reason;
+ int tout_msec;
+ u32 tmp;
+
+ /* sil24 does the right thing(tm) without any protection */
+ ata_set_sata_spd(ap);
+
+ tout_msec = 100;
+ if (sata_dev_present(ap))
+ tout_msec = 5000;
- /* sil24 doesn't report device signature after hard reset */
- return sata_std_hardreset(ap, verbose, &dummy_class);
+ writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
+ tmp = ata_wait_register(port + PORT_CTRL_STAT,
+ PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
+
+ /* SStatus oscillates between zero and valid status for short
+ * duration after DEV_RST, give it time to settle.
+ */
+ msleep(100);
+
+ if (tmp & PORT_CS_DEV_RST) {
+ if (!sata_dev_present(ap))
+ return 0;
+ reason = "link not ready";
+ goto err;
+ }
+
+ if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ reason = "device not ready";
+ goto err;
+ }
+
+ /* sil24 doesn't report device class code after hardreset,
+ * leave *class alone.
+ */
+ return 0;
+
+ err:
+ printk(KERN_ERR "ata%u: hardreset failed (%s)\n", ap->id, reason);
+ return -EIO;
}
static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)
@@ -532,6 +598,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
struct sil24_prb *prb;
struct sil24_sge *sge;
+ u16 ctrl = 0;
switch (qc->tf.protocol) {
case ATA_PROT_PIO:
@@ -539,7 +606,6 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
case ATA_PROT_NODATA:
prb = &cb->ata.prb;
sge = cb->ata.sge;
- prb->ctrl = 0;
break;
case ATA_PROT_ATAPI:
@@ -552,12 +618,10 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
if (qc->tf.flags & ATA_TFLAG_WRITE)
- prb->ctrl = PRB_CTRL_PACKET_WRITE;
+ ctrl = PRB_CTRL_PACKET_WRITE;
else
- prb->ctrl = PRB_CTRL_PACKET_READ;
- } else
- prb->ctrl = 0;
-
+ ctrl = PRB_CTRL_PACKET_READ;
+ }
break;
default:
@@ -566,6 +630,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
BUG();
}
+ prb->ctrl = cpu_to_le16(ctrl);
ata_tf_to_fis(&qc->tf, prb->fis, 0);
if (qc->flags & ATA_QCFLAG_DMAMAP)
@@ -580,6 +645,8 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+ writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
+
return 0;
}
@@ -728,6 +795,10 @@ static inline void sil24_host_intr(struct ata_port *ap)
slot_stat = readl(port + PORT_SLOT_STAT);
if (!(slot_stat & HOST_SSTAT_ATTN)) {
struct sil24_port_priv *pp = ap->private_data;
+
+ if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
+ writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT);
+
/*
* !HOST_SSAT_ATTN guarantees successful completion,
* so reading back tf registers is unnecessary for
@@ -859,6 +930,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
void __iomem *host_base = NULL;
void __iomem *port_base = NULL;
int i, rc;
+ u32 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -911,35 +983,51 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/*
* Configure the device
*/
- /*
- * FIXME: This device is certainly 64-bit capable. We just
- * don't know how to use it. After fixing 32bit activation in
- * this function, enable 64bit masks here.
- */
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (rc) {
- dev_printk(KERN_ERR, &pdev->dev,
- "32-bit DMA enable failed\n");
- goto out_free;
- }
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
- if (rc) {
- dev_printk(KERN_ERR, &pdev->dev,
- "32-bit consistent DMA enable failed\n");
- goto out_free;
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (rc) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
+ goto out_free;
+ }
+ }
+ } else {
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ goto out_free;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ goto out_free;
+ }
}
/* GPIO off */
writel(0, host_base + HOST_FLASH_CMD);
- /* Mask interrupts during initialization */
+ /* Apply workaround for completion IRQ loss on PCI-X errata */
+ if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
+ tmp = readl(host_base + HOST_CTRL);
+ if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Applying completion IRQ loss on PCI-X "
+ "errata fix\n");
+ else
+ probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
+ }
+
+ /* clear global reset & mask interrupts during initialization */
writel(0, host_base + HOST_CTRL);
for (i = 0; i < probe_ent->n_ports; i++) {
void __iomem *port = port_base + i * PORT_REGS_SIZE;
unsigned long portu = (unsigned long)port;
- u32 tmp;
- int cnt;
probe_ent->port[i].cmd_addr = portu + PORT_PRB;
probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
@@ -953,18 +1041,20 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tmp = readl(port + PORT_CTRL_STAT);
if (tmp & PORT_CS_PORT_RST) {
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
- readl(port + PORT_CTRL_STAT); /* sync */
- for (cnt = 0; cnt < 10; cnt++) {
- msleep(10);
- tmp = readl(port + PORT_CTRL_STAT);
- if (!(tmp & PORT_CS_PORT_RST))
- break;
- }
+ tmp = ata_wait_register(port + PORT_CTRL_STAT,
+ PORT_CS_PORT_RST,
+ PORT_CS_PORT_RST, 10, 100);
if (tmp & PORT_CS_PORT_RST)
dev_printk(KERN_ERR, &pdev->dev,
"failed to clear port RST\n");
}
+ /* Configure IRQ WoC */
+ if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC)
+ writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
+ else
+ writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
/* Zero error counters. */
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
writel(0x8000, port + PORT_CRC_ERR_THRESH);
@@ -973,14 +1063,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
writel(0x0000, port + PORT_CRC_ERR_CNT);
writel(0x0000, port + PORT_HSHK_ERR_CNT);
- /* FIXME: 32bit activation? */
- writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
- writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
+ /* Always use 64bit activation */
+ writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
/* Configure interrupts */
writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
- writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
- port + PORT_IRQ_ENABLE_SET);
+ writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
+ PORT_IRQ_SDB_NOTIFY, port + PORT_IRQ_ENABLE_SET);
/* Clear interrupts */
writel(0x0fff0fff, port + PORT_IRQ_STAT);
@@ -988,11 +1077,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Clear port multiplier enable and resume bits */
writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
-
- /* Reset itself */
- if (__sil24_reset_controller(port))
- dev_printk(KERN_ERR, &pdev->dev,
- "failed to reset controller\n");
}
/* Turn on interrupts */
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index eb3cf5b534d..3097821688d 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -87,7 +87,6 @@ static struct scsi_host_template sis_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = ATA_MAX_PRD,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index a20bc815475..d5eb5375e26 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -257,7 +257,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
int len, index;
/* Find the ata_port */
- ap = (struct ata_port *) &shost->hostdata[0];
+ ap = ata_shost_to_port(shost);
if (ap == NULL)
return 0;
@@ -290,7 +290,6 @@ static struct scsi_host_template k2_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 13dba63f616..4c07ba1f6e6 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -182,7 +182,6 @@ static struct scsi_host_template pdc_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 513dd78ea6f..15f81bfc30f 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -81,7 +81,6 @@ static struct scsi_host_template uli_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index de4e0eb224b..17aefab5f42 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -94,7 +94,6 @@ static struct scsi_host_template svia_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index b7d6a31628c..0372be7ff1c 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -270,7 +270,6 @@ static struct scsi_host_template vsc_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 5f0fdfb2618..1c75646f968 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1537,8 +1537,8 @@ int scsi_error_handler(void *data)
* what we need to do to get it up and online again (if we can).
* If we fail, we end up taking the thing offline.
*/
- if (shost->hostt->eh_strategy_handler)
- shost->hostt->eh_strategy_handler(shost);
+ if (shost->transportt->eh_strategy_handler)
+ shost->transportt->eh_strategy_handler(shost);
else
scsi_unjam_host(shost);