summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-06 21:42:33 +0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-06 21:42:33 +0400
commit00dd7b7d26a3bf3780cfcebfdde2b86126b3a082 (patch)
tree5129fd1abc99d0c58a520938f28bf330ae94ef30 /drivers/scsi
parent58b3ac07fed31ffc1349380b78305af6522fe1f4 (diff)
parent6e1e63259b1e01f047796e7985d960ca040993e6 (diff)
downloadlinux-00dd7b7d26a3bf3780cfcebfdde2b86126b3a082.tar.xz
Merge ../linux-2.6
Conflicts: arch/ia64/hp/sim/simscsi.c Stylistic differences in two separate fixes for buffer->request_buffer problem. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ahci.c10
-rw-r--r--drivers/scsi/aic7xxx/aicasm/Makefile2
-rw-r--r--drivers/scsi/libata-eh.c69
-rw-r--r--drivers/scsi/sata_promise.c7
-rw-r--r--drivers/scsi/scsi_ioctl.c5
5 files changed, 56 insertions, 37 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 77e7202a0eba..904c25fb4ba4 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -940,14 +940,8 @@ static void ahci_host_intr(struct ata_port *ap)
return;
/* ignore interim PIO setup fis interrupts */
- if (ata_tag_valid(ap->active_tag)) {
- struct ata_queued_cmd *qc =
- ata_qc_from_tag(ap, ap->active_tag);
-
- if (qc && qc->tf.protocol == ATA_PROT_PIO &&
- (status & PORT_IRQ_PIOS_FIS))
- return;
- }
+ if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
+ return;
if (ata_ratelimit())
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
diff --git a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile
index 8c91fda6482c..b98c5c1056c3 100644
--- a/drivers/scsi/aic7xxx/aicasm/Makefile
+++ b/drivers/scsi/aic7xxx/aicasm/Makefile
@@ -14,6 +14,8 @@ LIBS= -ldb
clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
# Override default kernel CFLAGS. This is a userland app.
AICASM_CFLAGS:= -I/usr/include -I.
+LEX= flex
+YACC= bison
YFLAGS= -d
NOMAN= noman
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 4b6aa30f4d68..29f59345305d 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -764,12 +764,27 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev,
unsigned int action)
{
unsigned long flags;
+ struct ata_eh_info *ehi = &ap->eh_info;
+ struct ata_eh_context *ehc = &ap->eh_context;
spin_lock_irqsave(ap->lock, flags);
- ata_eh_clear_action(dev, &ap->eh_info, action);
+ /* Reset is represented by combination of actions and EHI
+ * flags. Suck in all related bits before clearing eh_info to
+ * avoid losing requested action.
+ */
+ if (action & ATA_EH_RESET_MASK) {
+ ehc->i.action |= ehi->action & ATA_EH_RESET_MASK;
+ ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK;
+
+ /* make sure all reset actions are cleared & clear EHI flags */
+ action |= ATA_EH_RESET_MASK;
+ ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+ }
+
+ ata_eh_clear_action(dev, ehi, action);
- if (!(ap->eh_context.i.flags & ATA_EHI_QUIET))
+ if (!(ehc->i.flags & ATA_EHI_QUIET))
ap->pflags |= ATA_PFLAG_RECOVERED;
spin_unlock_irqrestore(ap->lock, flags);
@@ -790,6 +805,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev,
static void ata_eh_done(struct ata_port *ap, struct ata_device *dev,
unsigned int action)
{
+ /* if reset is complete, clear all reset actions & reset modifier */
+ if (action & ATA_EH_RESET_MASK) {
+ action |= ATA_EH_RESET_MASK;
+ ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+ }
+
ata_eh_clear_action(dev, &ap->eh_context.i, action);
}
@@ -1276,8 +1297,6 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io,
static void ata_eh_autopsy(struct ata_port *ap)
{
struct ata_eh_context *ehc = &ap->eh_context;
- unsigned int action = ehc->i.action;
- struct ata_device *failed_dev = NULL;
unsigned int all_err_mask = 0;
int tag, is_io = 0;
u32 serror;
@@ -1294,7 +1313,7 @@ static void ata_eh_autopsy(struct ata_port *ap)
ehc->i.serror |= serror;
ata_eh_analyze_serror(ap);
} else if (rc != -EOPNOTSUPP)
- action |= ATA_EH_HARDRESET;
+ ehc->i.action |= ATA_EH_HARDRESET;
/* analyze NCQ failure */
ata_eh_analyze_ncq_error(ap);
@@ -1315,7 +1334,7 @@ static void ata_eh_autopsy(struct ata_port *ap)
qc->err_mask |= ehc->i.err_mask;
/* analyze TF */
- action |= ata_eh_analyze_tf(qc, &qc->result_tf);
+ ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf);
/* DEV errors are probably spurious in case of ATA_BUS error */
if (qc->err_mask & AC_ERR_ATA_BUS)
@@ -1329,11 +1348,11 @@ static void ata_eh_autopsy(struct ata_port *ap)
/* SENSE_VALID trumps dev/unknown error and revalidation */
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
- action &= ~ATA_EH_REVALIDATE;
+ ehc->i.action &= ~ATA_EH_REVALIDATE;
}
/* accumulate error info */
- failed_dev = qc->dev;
+ ehc->i.dev = qc->dev;
all_err_mask |= qc->err_mask;
if (qc->flags & ATA_QCFLAG_IO)
is_io = 1;
@@ -1342,25 +1361,22 @@ static void ata_eh_autopsy(struct ata_port *ap)
/* enforce default EH actions */
if (ap->pflags & ATA_PFLAG_FROZEN ||
all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
- action |= ATA_EH_SOFTRESET;
+ ehc->i.action |= ATA_EH_SOFTRESET;
else if (all_err_mask)
- action |= ATA_EH_REVALIDATE;
+ ehc->i.action |= ATA_EH_REVALIDATE;
/* if we have offending qcs and the associated failed device */
- if (failed_dev) {
+ if (ehc->i.dev) {
/* speed down */
- action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask);
+ ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
+ all_err_mask);
/* perform per-dev EH action only on the offending device */
- ehc->i.dev_action[failed_dev->devno] |=
- action & ATA_EH_PERDEV_MASK;
- action &= ~ATA_EH_PERDEV_MASK;
+ ehc->i.dev_action[ehc->i.dev->devno] |=
+ ehc->i.action & ATA_EH_PERDEV_MASK;
+ ehc->i.action &= ~ATA_EH_PERDEV_MASK;
}
- /* record autopsy result */
- ehc->i.dev = failed_dev;
- ehc->i.action |= action;
-
DPRINTK("EXIT\n");
}
@@ -1483,6 +1499,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
ata_reset_fn_t reset;
int i, did_followup_srst, rc;
+ /* about to reset */
+ ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+
/* Determine which reset to use and record in ehc->i.action.
* prereset() may examine and modify it.
*/
@@ -1531,8 +1550,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
reset == softreset ? "soft" : "hard");
- /* reset */
- ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
+ /* mark that this EH session started with reset */
ehc->i.flags |= ATA_EHI_DID_RESET;
rc = ata_do_reset(ap, reset, classes);
@@ -1595,7 +1613,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
postreset(ap, classes);
/* reset successful, schedule revalidation */
- ata_eh_done(ap, NULL, ATA_EH_RESET_MASK);
+ ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
ehc->i.action |= ATA_EH_REVALIDATE;
}
@@ -1848,15 +1866,16 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
for (i = 0; i < ata_port_max_devices(ap); i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_absent(dev) || ata_dev_ready(dev))
+ if (!(dev->flags & ATA_DFLAG_SUSPENDED))
break;
}
if (i == ata_port_max_devices(ap))
return 1;
- /* always thaw frozen port and recover failed devices */
- if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap))
+ /* thaw frozen port, resume link and recover failed devices */
+ if ((ap->pflags & ATA_PFLAG_FROZEN) ||
+ (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
return 0;
/* skip if class codes for all vacant slots are ATA_DEV_NONE */
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 64631bd38952..4776f4e55839 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -269,8 +269,15 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20619 },
+/* TODO: remove all associated board_20771 code, as it completely
+ * duplicates board_2037x code, unless reason for separation can be
+ * divined.
+ */
+#if 0
{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20771 },
+#endif
+
{ } /* terminate list */
};
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index a89c4115cfba..32293f451669 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -110,11 +110,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
sshdr.asc, sshdr.ascq);
break;
case NOT_READY: /* This happens if there is no disc in drive */
- if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
- printk(KERN_INFO "Device not ready. Make sure"
- " there is a disc in the drive.\n");
+ if (sdev->removable)
break;
- }
case UNIT_ATTENTION:
if (sdev->removable) {
sdev->changed = 1;