summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/Kconfig12
-rw-r--r--drivers/ata/ahci.c111
-rw-r--r--drivers/ata/ata_generic.c6
-rw-r--r--drivers/ata/ata_piix.c22
-rw-r--r--drivers/ata/libata-core.c31
-rw-r--r--drivers/ata/libata-eh.c6
-rw-r--r--drivers/ata/libata-scsi.c304
-rw-r--r--drivers/ata/libata-sff.c63
-rw-r--r--drivers/ata/pata_atiixp.c11
-rw-r--r--drivers/ata/pata_cmd64x.c23
-rw-r--r--drivers/ata/pata_cs5530.c3
-rw-r--r--drivers/ata/pata_hpt37x.c6
-rw-r--r--drivers/ata/pata_hpt3x2n.c6
-rw-r--r--drivers/ata/pata_it821x.c4
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c5
-rw-r--r--drivers/ata/pata_jmicron.c18
-rw-r--r--drivers/ata/pata_legacy.c8
-rw-r--r--drivers/ata/pata_platform.c3
-rw-r--r--drivers/ata/pata_qdi.c4
-rw-r--r--drivers/ata/pata_rz1000.c8
-rw-r--r--drivers/ata/pata_sil680.c2
-rw-r--r--drivers/ata/pata_via.c15
-rw-r--r--drivers/ata/pata_winbond.c4
-rw-r--r--drivers/ata/sata_mv.c5
-rw-r--r--drivers/ata/sata_nv.c22
-rw-r--r--drivers/ata/sata_svw.c82
-rw-r--r--drivers/ata/sata_uli.c3
-rw-r--r--drivers/ata/sata_via.c13
-rw-r--r--drivers/ata/sata_vsc.c43
29 files changed, 514 insertions, 329 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 984ab284382..1c94b43d2c9 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -19,6 +19,10 @@ config ATA
if ATA
+config ATA_NONSTANDARD
+ bool
+ default n
+
config SATA_AHCI
tristate "AHCI SATA support"
depends on PCI
@@ -40,9 +44,9 @@ config ATA_PIIX
tristate "Intel PIIX/ICH SATA support"
depends on PCI
help
- This option enables support for ICH5/6/7/8 Serial ATA.
- If PATA support was enabled previously, this enables
- support for select Intel PIIX/ICH PATA host controllers.
+ This option enables support for ICH5/6/7/8 Serial ATA
+ and support for PATA on the Intel PIIX3/PIIX4/ICH series
+ PATA host controllers.
If unsure, say N.
@@ -381,7 +385,7 @@ config PATA_OPTI
If unsure, say N.
config PATA_OPTIDMA
- tristate "OPTI FireStar PATA support (Veyr Experimental)"
+ tristate "OPTI FireStar PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables DMA/PIO support for the later OPTi
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f36da488a2c..48616c6fee9 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -75,6 +75,7 @@ enum {
AHCI_CMD_CLR_BUSY = (1 << 10),
RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
+ RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
board_ahci = 0,
@@ -202,6 +203,10 @@ struct ahci_port_priv {
dma_addr_t cmd_tbl_dma;
void *rx_fis;
dma_addr_t rx_fis_dma;
+ /* for NCQ spurious interrupt analysis */
+ int ncq_saw_spurious_sdb_cnt;
+ unsigned int ncq_saw_d2h:1;
+ unsigned int ncq_saw_dmas:1;
};
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
@@ -361,7 +366,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
{ PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
{ PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
- { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */
+ { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */
{ PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
@@ -402,6 +407,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
@@ -578,35 +591,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
{
u32 cmd, scontrol;
- cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
-
- if (cap & HOST_CAP_SSC) {
- /* enable transitions to slumber mode */
- scontrol = readl(port_mmio + PORT_SCR_CTL);
- if ((scontrol & 0x0f00) > 0x100) {
- scontrol &= ~0xf00;
- writel(scontrol, port_mmio + PORT_SCR_CTL);
- }
-
- /* put device into slumber mode */
- writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD);
-
- /* wait for the transition to complete */
- ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER,
- PORT_CMD_ICC_SLUMBER, 1, 50);
- }
+ if (!(cap & HOST_CAP_SSS))
+ return;
- /* put device into listen mode */
- if (cap & HOST_CAP_SSS) {
- /* first set PxSCTL.DET to 0 */
- scontrol = readl(port_mmio + PORT_SCR_CTL);
- scontrol &= ~0xf;
- writel(scontrol, port_mmio + PORT_SCR_CTL);
+ /* put device into listen mode, first set PxSCTL.DET to 0 */
+ scontrol = readl(port_mmio + PORT_SCR_CTL);
+ scontrol &= ~0xf;
+ writel(scontrol, port_mmio + PORT_SCR_CTL);
- /* then set PxCMD.SUD to 0 */
- cmd &= ~PORT_CMD_SPIN_UP;
- writel(cmd, port_mmio + PORT_CMD);
- }
+ /* then set PxCMD.SUD to 0 */
+ cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
+ cmd &= ~PORT_CMD_SPIN_UP;
+ writel(cmd, port_mmio + PORT_CMD);
}
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
@@ -645,8 +641,6 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
u32 cap_save, impl_save, tmp;
cap_save = readl(mmio + HOST_CAP);
- cap_save &= ( (1<<28) | (1<<17) );
- cap_save |= (1 << 27);
impl_save = readl(mmio + HOST_PORTS_IMPL);
/* global controller reset */
@@ -909,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(ap->device, &tf);
- tf.command = 0xff;
+ tf.command = 0x80;
ata_tf_to_fis(&tf, d2h_fis, 0);
rc = sata_std_hardreset(ap, class);
@@ -1120,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap)
void __iomem *mmio = ap->host->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
struct ata_eh_info *ehi = &ap->eh_info;
+ struct ahci_port_priv *pp = ap->private_data;
u32 status, qc_active;
- int rc;
+ int rc, known_irq = 0;
status = readl(port_mmio + PORT_IRQ_STAT);
writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1148,17 +1143,53 @@ static void ahci_host_intr(struct ata_port *ap)
/* hmmm... a spurious interupt */
- /* some devices send D2H reg with I bit set during NCQ command phase */
- if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
+ /* if !NCQ, ignore. No modern ATA device has broken HSM
+ * implementation for non-NCQ commands.
+ */
+ if (!ap->sactive)
return;
- /* ignore interim PIO setup fis interrupts */
- if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
- return;
+ if (status & PORT_IRQ_D2H_REG_FIS) {
+ if (!pp->ncq_saw_d2h)
+ ata_port_printk(ap, KERN_INFO,
+ "D2H reg with I during NCQ, "
+ "this message won't be printed again\n");
+ pp->ncq_saw_d2h = 1;
+ known_irq = 1;
+ }
+
+ if (status & PORT_IRQ_DMAS_FIS) {
+ if (!pp->ncq_saw_dmas)
+ ata_port_printk(ap, KERN_INFO,
+ "DMAS FIS during NCQ, "
+ "this message won't be printed again\n");
+ pp->ncq_saw_dmas = 1;
+ known_irq = 1;
+ }
+
+ if (status & PORT_IRQ_SDB_FIS &&
+ pp->ncq_saw_spurious_sdb_cnt < 10) {
+ /* SDB FIS containing spurious completions might be
+ * dangerous, we need to know more about them. Print
+ * more of it.
+ */
+ const u32 *f = pp->rx_fis + RX_FIS_SDB;
+
+ ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ "
+ "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n",
+ readl(port_mmio + PORT_CMD_ISSUE),
+ readl(port_mmio + PORT_SCR_ACT),
+ le32_to_cpu(f[0]), le32_to_cpu(f[1]),
+ pp->ncq_saw_spurious_sdb_cnt < 10 ?
+ "" : ", shutting up");
+
+ pp->ncq_saw_spurious_sdb_cnt++;
+ known_irq = 1;
+ }
- if (ata_ratelimit())
+ if (!known_irq)
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
- "(irq_stat 0x%x active_tag %d sactive 0x%x)\n",
+ "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
status, ap->active_tag, ap->sactive);
}
@@ -1251,7 +1282,7 @@ static void ahci_thaw(struct ata_port *ap)
/* clear IRQ */
tmp = readl(port_mmio + PORT_IRQ_STAT);
writel(tmp, port_mmio + PORT_IRQ_STAT);
- writel(1 << ap->id, mmio + HOST_IRQ_STAT);
+ writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
/* turn IRQ back on */
writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 908751d27e7..24af56081b5 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap)
/**
* generic_set_mode - mode setting
* @ap: interface to set up
+ * @unused: returned device on error
*
* Use a non standard set_mode function. We don't want to be tuned.
* The BIOS configured everything. Our job is not to fiddle. We
@@ -71,7 +72,7 @@ static void generic_error_handler(struct ata_port *ap)
* and respect them.
*/
-static void generic_set_mode(struct ata_port *ap)
+static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int dma_enabled = 0;
int i;
@@ -82,7 +83,7 @@ static void generic_set_mode(struct ata_port *ap)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_enabled(dev)) {
+ if (ata_dev_ready(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
@@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap)
}
}
}
+ return 0;
}
static struct scsi_host_template generic_sht = {
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c7de0bb1591..47701b286f8 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -226,14 +226,26 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
- /* Enterprise Southbridge 2 (where's the datasheet?) */
+ /* Enterprise Southbridge 2 (631xESB/632xESB) */
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
+ /* SATA Controller 1 IDE (ICH8) */
{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* SATA Controller 2 IDE (ICH8, ditto) */
+ /* SATA Controller 2 IDE (ICH8) */
{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* Mobile SATA Controller IDE (ICH8M, ditto) */
+ /* Mobile SATA Controller IDE (ICH8M) */
{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
{ } /* terminate list */
};
@@ -330,7 +342,7 @@ static const struct ata_port_operations ich_pata_ops = {
.port_start = ata_port_start,
.port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .host_stop = piix_host_stop,
};
static const struct ata_port_operations piix_sata_ops = {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 011c0a8a2dc..667acd28336 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1037,7 +1037,7 @@ static unsigned int ata_id_xfermask(const u16 *id)
* the PIO timing number for the maximum. Turn it into
* a mask.
*/
- u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
+ u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF;
if (mode < 5) /* Valid PIO range */
pio_mask = (2 << mode) - 1;
else
@@ -1250,6 +1250,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
ata_sg_init(qc, sg, n_elem);
qc->nsect = buflen / ATA_SECT_SIZE;
+ qc->nbytes = buflen;
}
qc->private_data = &wait;
@@ -1332,7 +1333,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
}
/**
- * ata_exec_internal_sg - execute libata internal command
+ * ata_exec_internal - execute libata internal command
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
@@ -1353,11 +1354,17 @@ unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen)
{
- struct scatterlist sg;
+ struct scatterlist *psg = NULL, sg;
+ unsigned int n_elem = 0;
- sg_init_one(&sg, buf, buflen);
+ if (dma_dir != DMA_NONE) {
+ WARN_ON(!buf);
+ sg_init_one(&sg, buf, buflen);
+ psg = &sg;
+ n_elem++;
+ }
- return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
+ return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem);
}
/**
@@ -2425,18 +2432,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
int i, rc = 0, used_dma = 0, found = 0;
/* has private set_mode? */
- if (ap->ops->set_mode) {
- /* FIXME: make ->set_mode handle no device case and
- * return error code and failing device on failure.
- */
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- if (ata_dev_ready(&ap->device[i])) {
- ap->ops->set_mode(ap);
- break;
- }
- }
- return 0;
- }
+ if (ap->ops->set_mode)
+ return ap->ops->set_mode(ap, r_failed_dev);
/* step 1: calculate xfer_mask */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 08ad44b3e48..748435807d6 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1796,7 +1796,7 @@ static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
*r_failed_dev = dev;
DPRINTK("EXIT\n");
- return 0;
+ return rc;
}
/**
@@ -1979,6 +1979,10 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+ /* collect port action mask recorded in dev actions */
+ ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK;
+ ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK;
+
/* process hotplug request */
if (dev->flags & ATA_DFLAG_DETACH)
ata_eh_detach_dev(dev);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 664e1377b54..73902d33576 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -51,7 +51,7 @@
#define SECTOR_SIZE 512
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
@@ -273,8 +273,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
{
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
- u8 args[7];
- struct scsi_sense_hdr sshdr;
+ u8 args[7], *sensebuf = NULL;
+ int cmd_result;
if (arg == NULL)
return -EINVAL;
@@ -282,10 +282,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT;
+ sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
+ if (!sensebuf)
+ return -ENOMEM;
+
memset(scsi_cmd, 0, sizeof(scsi_cmd));
scsi_cmd[0] = ATA_16;
scsi_cmd[1] = (3 << 1); /* Non-data */
- /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
scsi_cmd[4] = args[1];
scsi_cmd[6] = args[2];
scsi_cmd[8] = args[3];
@@ -295,11 +299,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
- if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr,
- (10*HZ), 5))
+ cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
+ sensebuf, (10*HZ), 5, 0);
+
+ if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
+ u8 *desc = sensebuf + 8;
+ cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
+
+ /* If we set cc then ATA pass-through will cause a
+ * check condition even if no error. Filter that. */
+ if (cmd_result & SAM_STAT_CHECK_CONDITION) {
+ struct scsi_sense_hdr sshdr;
+ scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
+ &sshdr);
+ if (sshdr.sense_key==0 &&
+ sshdr.asc==0 && sshdr.ascq==0)
+ cmd_result &= ~SAM_STAT_CHECK_CONDITION;
+ }
+
+ /* Send userspace ATA registers */
+ if (sensebuf[0] == 0x72 && /* format is "descriptor" */
+ desc[0] == 0x09) {/* code is "ATA Descriptor" */
+ args[0] = desc[13]; /* status */
+ args[1] = desc[3]; /* error */
+ args[2] = desc[5]; /* sector count (0:7) */
+ args[3] = desc[7]; /* lbal */
+ args[4] = desc[9]; /* lbam */
+ args[5] = desc[11]; /* lbah */
+ args[6] = desc[12]; /* select */
+ if (copy_to_user(arg, args, sizeof(args)))
+ rc = -EFAULT;
+ }
+ }
+
+ if (cmd_result) {
rc = -EIO;
+ goto error;
+ }
- /* Need code to retrieve data from check condition? */
+ error:
+ kfree(sensebuf);
return rc;
}
@@ -372,7 +411,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
if (cmd->use_sg) {
qc->__sg = (struct scatterlist *) cmd->request_buffer;
qc->n_elem = cmd->use_sg;
- } else {
+ } else if (cmd->request_bufflen) {
qc->__sg = &qc->sgent;
qc->n_elem = 1;
}
@@ -935,7 +974,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
/**
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
* (to start). Perhaps these commands should be preceded by
@@ -948,22 +986,25 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- const u8 *scsicmd)
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
+ const u8 *cdb = scmd->cmnd;
+
+ if (scmd->cmd_len < 5)
+ goto invalid_fld;
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf->protocol = ATA_PROT_NODATA;
- if (scsicmd[1] & 0x1) {
+ if (cdb[1] & 0x1) {
; /* ignore IMMED bit, violates sat-r05 */
}
- if (scsicmd[4] & 0x2)
+ if (cdb[4] & 0x2)
goto invalid_fld; /* LOEJ bit set not supported */
- if (((scsicmd[4] >> 4) & 0xf) != 0)
+ if (((cdb[4] >> 4) & 0xf) != 0)
goto invalid_fld; /* power conditions not supported */
- if (scsicmd[4] & 0x1) {
+ if (cdb[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
if (qc->dev->flags & ATA_DFLAG_LBA) {
@@ -981,11 +1022,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else {
- tf->nsect = 0; /* time period value (0 implies now) */
- tf->command = ATA_CMD_STANDBY;
- /* Consider: ATA STANDBY IMMEDIATE command */
- }
+ } else
+ /* Issue ATA STANDBY IMMEDIATE command */
+ tf->command = ATA_CMD_STANDBYNOW1;
+
/*
* Standby and Idle condition timers could be implemented but that
* would require libata to implement the Power condition mode page
@@ -996,7 +1036,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
}
@@ -1005,7 +1045,6 @@ invalid_fld:
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate (ignored)
*
* Sets up an ATA taskfile to issue FLUSH CACHE or
* FLUSH CACHE EXT.
@@ -1016,8 +1055,7 @@ invalid_fld:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &qc->tf;
@@ -1034,7 +1072,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
/**
* scsi_6_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 6-byte commands.
*
@@ -1042,18 +1080,17 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("six-byte command\n");
- lba |= ((u64)scsicmd[2]) << 8;
- lba |= ((u64)scsicmd[3]);
+ lba |= ((u64)cdb[2]) << 8;
+ lba |= ((u64)cdb[3]);
- len |= ((u32)scsicmd[4]);
+ len |= ((u32)cdb[4]);
*plba = lba;
*plen = len;
@@ -1061,7 +1098,7 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_10_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 10-byte commands.
*
@@ -1069,21 +1106,20 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("ten-byte command\n");
- lba |= ((u64)scsicmd[2]) << 24;
- lba |= ((u64)scsicmd[3]) << 16;
- lba |= ((u64)scsicmd[4]) << 8;
- lba |= ((u64)scsicmd[5]);
+ lba |= ((u64)cdb[2]) << 24;
+ lba |= ((u64)cdb[3]) << 16;
+ lba |= ((u64)cdb[4]) << 8;
+ lba |= ((u64)cdb[5]);
- len |= ((u32)scsicmd[7]) << 8;
- len |= ((u32)scsicmd[8]);
+ len |= ((u32)cdb[7]) << 8;
+ len |= ((u32)cdb[8]);
*plba = lba;
*plen = len;
@@ -1091,7 +1127,7 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_16_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 16-byte commands.
*
@@ -1099,27 +1135,26 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("sixteen-byte command\n");
- lba |= ((u64)scsicmd[2]) << 56;
- lba |= ((u64)scsicmd[3]) << 48;
- lba |= ((u64)scsicmd[4]) << 40;
- lba |= ((u64)scsicmd[5]) << 32;
- lba |= ((u64)scsicmd[6]) << 24;
- lba |= ((u64)scsicmd[7]) << 16;
- lba |= ((u64)scsicmd[8]) << 8;
- lba |= ((u64)scsicmd[9]);
+ lba |= ((u64)cdb[2]) << 56;
+ lba |= ((u64)cdb[3]) << 48;
+ lba |= ((u64)cdb[4]) << 40;
+ lba |= ((u64)cdb[5]) << 32;
+ lba |= ((u64)cdb[6]) << 24;
+ lba |= ((u64)cdb[7]) << 16;
+ lba |= ((u64)cdb[8]) << 8;
+ lba |= ((u64)cdb[9]);
- len |= ((u32)scsicmd[10]) << 24;
- len |= ((u32)scsicmd[11]) << 16;
- len |= ((u32)scsicmd[12]) << 8;
- len |= ((u32)scsicmd[13]);
+ len |= ((u32)cdb[10]) << 24;
+ len |= ((u32)cdb[11]) << 16;
+ len |= ((u32)cdb[12]) << 8;
+ len |= ((u32)cdb[13]);
*plba = lba;
*plen = len;
@@ -1128,7 +1163,6 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts SCSI VERIFY command to an ATA READ VERIFY command.
*
@@ -1138,23 +1172,28 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
u64 dev_sectors = qc->dev->n_sectors;
+ const u8 *cdb = scmd->cmnd;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if (scsicmd[0] == VERIFY)
- scsi_10_lba_len(scsicmd, &block, &n_block);
- else if (scsicmd[0] == VERIFY_16)
- scsi_16_lba_len(scsicmd, &block, &n_block);
- else
+ if (cdb[0] == VERIFY) {
+ if (scmd->cmd_len < 10)
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ } else if (cdb[0] == VERIFY_16) {
+ if (scmd->cmd_len < 16)
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ } else
goto invalid_fld;
if (!n_block)
@@ -1229,24 +1268,23 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
/**
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts any of six SCSI read/write commands into the
* ATA counterpart, including starting sector (LBA),
@@ -1262,29 +1300,33 @@ nothing_to_do:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+ const u8 *cdb = scmd->cmnd;
unsigned int tf_flags = 0;
u64 block;
u32 n_block;
int rc;
- if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
- scsicmd[0] == WRITE_16)
+ if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
tf_flags |= ATA_TFLAG_WRITE;
/* Calculate the SCSI LBA, transfer length and FUA. */
- switch (scsicmd[0]) {
+ switch (cdb[0]) {
case READ_10:
case WRITE_10:
- scsi_10_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 10))
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
case READ_6:
case WRITE_6:
- scsi_6_lba_len(scsicmd, &block, &n_block);
+ if (unlikely(scmd->cmd_len < 6))
+ goto invalid_fld;
+ scsi_6_lba_len(cdb, &block, &n_block);
/* for 6-byte r/w commands, transfer length 0
* means 256 blocks of data, not 0 block.
@@ -1294,8 +1336,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
break;
case READ_16:
case WRITE_16:
- scsi_16_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 16))
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
default:
@@ -1326,17 +1370,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
goto out_of_range;
/* treat all other errors as -EINVAL, fall through */
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
@@ -1456,7 +1500,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
ata_xlat_func_t xlat_func)
{
struct ata_queued_cmd *qc;
- u8 *scsicmd = cmd->cmnd;
int is_io = xlat_func == ata_scsi_rw_xlat;
VPRINTK("ENTER\n");
@@ -1488,7 +1531,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
qc->complete_fn = ata_scsi_qc_complete;
- if (xlat_func(qc, scsicmd))
+ if (xlat_func(qc))
goto early_finish;
/* select device, send command to hardware */
@@ -1539,7 +1582,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
@@ -1567,7 +1610,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- kunmap_atomic(buf - sg->offset, KM_USER0);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
@@ -2344,7 +2387,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
/**
* atapi_xlat - Initialize PACKET taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI CDB associated with this PACKET command
*
* LOCKING:
* spin_lock_irqsave(host lock)
@@ -2352,25 +2394,25 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
* RETURNS:
* Zero on success, non-zero on failure.
*/
-
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
int using_pio = (dev->flags & ATA_DFLAG_PIO);
- int nodata = (cmd->sc_data_direction == DMA_NONE);
+ int nodata = (scmd->sc_data_direction == DMA_NONE);
if (!using_pio)
/* Check whether ATAPI DMA is safe */
if (ata_check_atapi_dma(qc))
using_pio = 1;
- memcpy(&qc->cdb, scsicmd, dev->cdb_len);
+ memset(qc->cdb, 0, dev->cdb_len);
+ memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
qc->complete_fn = atapi_qc_complete;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
qc->tf.flags |= ATA_TFLAG_WRITE;
DPRINTK("direction: write\n");
}
@@ -2392,12 +2434,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+ if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
- qc->nbytes = cmd->request_bufflen;
+ qc->nbytes = scmd->request_bufflen;
return 0;
}
@@ -2517,28 +2559,27 @@ ata_scsi_map_proto(u8 byte1)
/**
* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI command to convert
*
* Handles either 12 or 16-byte versions of the CDB.
*
* RETURNS:
* Zero on success, non-zero on failure.
*/
-static unsigned int
-ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &(qc->tf);
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
+ const u8 *cdb = scmd->cmnd;
- if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
goto invalid_fld;
/* We may not issue DMA commands if no DMA mode is set */
if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld;
- if (scsicmd[1] & 0xe0)
+ if (cdb[1] & 0xe0)
/* PIO multi not supported yet */
goto invalid_fld;
@@ -2546,18 +2587,18 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
*/
- if (scsicmd[0] == ATA_16) {
+ if (cdb[0] == ATA_16) {
/*
* 16-byte CDB - may contain extended commands.
*
* If that is the case, copy the upper byte register values.
*/
- if (scsicmd[1] & 0x01) {
- tf->hob_feature = scsicmd[3];
- tf->hob_nsect = scsicmd[5];
- tf->hob_lbal = scsicmd[7];
- tf->hob_lbam = scsicmd[9];
- tf->hob_lbah = scsicmd[11];
+ if (cdb[1] & 0x01) {
+ tf->hob_feature = cdb[3];
+ tf->hob_nsect = cdb[5];
+ tf->hob_lbal = cdb[7];
+ tf->hob_lbam = cdb[9];
+ tf->hob_lbah = cdb[11];
tf->flags |= ATA_TFLAG_LBA48;
} else
tf->flags &= ~ATA_TFLAG_LBA48;
@@ -2565,26 +2606,26 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
/*
* Always copy low byte, device and command registers.
*/
- tf->feature = scsicmd[4];
- tf->nsect = scsicmd[6];
- tf->lbal = scsicmd[8];
- tf->lbam = scsicmd[10];
- tf->lbah = scsicmd[12];
- tf->device = scsicmd[13];
- tf->command = scsicmd[14];
+ tf->feature = cdb[4];
+ tf->nsect = cdb[6];
+ tf->lbal = cdb[8];
+ tf->lbam = cdb[10];
+ tf->lbah = cdb[12];
+ tf->device = cdb[13];
+ tf->command = cdb[14];
} else {
/*
* 12-byte CDB - incapable of extended commands.
*/
tf->flags &= ~ATA_TFLAG_LBA48;
- tf->feature = scsicmd[3];
- tf->nsect = scsicmd[4];
- tf->lbal = scsicmd[5];
- tf->lbam = scsicmd[6];
- tf->lbah = scsicmd[7];
- tf->device = scsicmd[8];
- tf->command = scsicmd[9];
+ tf->feature = cdb[3];
+ tf->nsect = cdb[4];
+ tf->lbal = cdb[5];
+ tf->lbam = cdb[6];
+ tf->lbah = cdb[7];
+ tf->device = cdb[8];
+ tf->command = cdb[9];
}
/*
* If slave is possible, enforce correct master/slave bit
@@ -2611,7 +2652,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
*/
tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
- if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ if (scmd->sc_data_direction == DMA_TO_DEVICE)
tf->flags |= ATA_TFLAG_WRITE;
/*
@@ -2620,7 +2661,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
+ qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
/* request result TF */
qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -2628,7 +2669,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
/* "Invalid field in cdb" */
return 1;
}
@@ -2701,22 +2742,29 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
#endif
}
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd,
+static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
void (*done)(struct scsi_cmnd *),
struct ata_device *dev)
{
int rc = 0;
+ if (unlikely(!scmd->cmd_len)) {
+ ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+ scmd->result = DID_ERROR << 16;
+ done(scmd);
+ return 0;
+ }
+
if (dev->class == ATA_DEV_ATA) {
ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
- cmd->cmnd[0]);
+ scmd->cmnd[0]);
if (xlat_func)
- rc = ata_scsi_translate(dev, cmd, done, xlat_func);
+ rc = ata_scsi_translate(dev, scmd, done, xlat_func);
else
- ata_scsi_simulate(dev, cmd, done);
+ ata_scsi_simulate(dev, scmd, done);
} else
- rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+ rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
return rc;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 10ee22ae5c1..12c88c58803 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -827,7 +827,8 @@ void ata_bmdma_error_handler(struct ata_port *ap)
*/
void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
{
- ata_bmdma_stop(qc);
+ if (qc->ap->ioaddr.bmdma_addr)
+ ata_bmdma_stop(qc);
}
#ifdef CONFIG_PCI
@@ -870,7 +871,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
bmdma = pci_resource_start(pdev, 4);
if (bmdma) {
- if (inb(bmdma + 2) & 0x80)
+ if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (inb(bmdma + 2) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
probe_ent->port[p].bmdma_addr = bmdma;
}
@@ -886,7 +888,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
bmdma = pci_resource_start(pdev, 4);
if (bmdma) {
bmdma += 8;
- if(inb(bmdma + 2) & 0x80)
+ if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (inb(bmdma + 2) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
probe_ent->port[p].bmdma_addr = bmdma;
}
@@ -914,13 +917,14 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
probe_ent->irq_flags = IRQF_SHARED;
if (port_mask & ATA_PORT_PRIMARY) {
- probe_ent->irq = ATA_PRIMARY_IRQ;
+ probe_ent->irq = ATA_PRIMARY_IRQ(pdev);
probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD;
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL;
if (bmdma) {
probe_ent->port[0].bmdma_addr = bmdma;
- if (inb(bmdma + 2) & 0x80)
+ if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (inb(bmdma + 2) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
}
ata_std_ports(&probe_ent->port[0]);
@@ -929,15 +933,16 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
if (port_mask & ATA_PORT_SECONDARY) {
if (probe_ent->irq)
- probe_ent->irq2 = ATA_SECONDARY_IRQ;
+ probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
else
- probe_ent->irq = ATA_SECONDARY_IRQ;
+ probe_ent->irq = ATA_SECONDARY_IRQ(pdev);
probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD;
probe_ent->port[1].altstatus_addr =
probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
if (bmdma) {
probe_ent->port[1].bmdma_addr = bmdma + 8;
- if (inb(bmdma + 10) & 0x80)
+ if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (inb(bmdma + 10) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
}
ata_std_ports(&probe_ent->port[1]);
@@ -1027,13 +1032,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
#endif
}
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- disable_dev_on_err = 0;
- goto err_out;
- }
-
- if (legacy_mode) {
+ if (!legacy_mode) {
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc) {
+ disable_dev_on_err = 0;
+ goto err_out;
+ }
+ } else {
+ /* Deal with combined mode hack. This side of the logic all
+ goes away once the combined mode hack is killed in 2.6.21 */
if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
struct resource *conflict, res;
res.start = ATA_PRIMARY_CMD;
@@ -1071,6 +1078,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
} else
legacy_mode |= ATA_PORT_SECONDARY;
+
+ if (legacy_mode & ATA_PORT_PRIMARY)
+ pci_request_region(pdev, 1, DRV_NAME);
+ if (legacy_mode & ATA_PORT_SECONDARY)
+ pci_request_region(pdev, 3, DRV_NAME);
+ /* If there is a DMA resource, allocate it */
+ pci_request_region(pdev, 4, DRV_NAME);
}
/* we have legacy mode, but all ports are unavailable */
@@ -1114,11 +1128,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
err_out_ent:
kfree(probe_ent);
err_out_regions:
- if (legacy_mode & ATA_PORT_PRIMARY)
- release_region(ATA_PRIMARY_CMD, 8);
- if (legacy_mode & ATA_PORT_SECONDARY)
- release_region(ATA_SECONDARY_CMD, 8);
- pci_release_regions(pdev);
+ /* All this conditional stuff is needed for the combined mode hack
+ until 2.6.21 when it can go */
+ if (legacy_mode) {
+ pci_release_region(pdev, 4);
+ if (legacy_mode & ATA_PORT_PRIMARY) {
+ release_region(ATA_PRIMARY_CMD, 8);
+ pci_release_region(pdev, 1);
+ }
+ if (legacy_mode & ATA_PORT_SECONDARY) {
+ release_region(ATA_SECONDARY_CMD, 8);
+ pci_release_region(pdev, 3);
+ }
+ } else
+ pci_release_regions(pdev);
err_out:
if (disable_dev_on_err)
pci_disable_device(pdev);
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 6f6672c5513..504e1dbfffd 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -36,15 +36,22 @@ enum {
static int atiixp_pre_reset(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- static struct pci_bits atiixp_enable_bits[] = {
+ static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
+ u8 udma;
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA80;
+ /* Hack from drivers/ide/pci. Really we want to know how to do the
+ raw detection not play follow the bios mode guess */
+ pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
+ if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
+ ap->cbl = ATA_CBL_PATA80;
+ else
+ ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 15841a56369..449162cbf93 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
static const u8 udma_data[] = {
- 0x31, 0x21, 0x11, 0x25, 0x15, 0x05
+ 0x30, 0x20, 0x10, 0x20, 0x10, 0x00
};
static const u8 mwdma_data[] = {
0x30, 0x20, 0x10
@@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
pci_read_config_byte(pdev, pciD, &regD);
pci_read_config_byte(pdev, pciU, &regU);
- regD &= ~(0x20 << shift);
- regU &= ~(0x35 << shift);
+ /* DMA bits off */
+ regD &= ~(0x20 << adev->devno);
+ /* DMA control bits */
+ regU &= ~(0x30 << shift);
+ /* DMA timing bits */
+ regU &= ~(0x05 << adev->devno);
- if (adev->dma_mode >= XFER_UDMA_0)
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ /* Merge thge timing value */
regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
- else
+ /* Merge the control bits */
+ regU |= 1 << adev->devno; /* UDMA on */
+ if (adev->dma_mode > 2) /* 15nS timing */
+ regU |= 4 << adev->devno;
+ } else
regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift;
regD |= 0x20 << adev->devno;
@@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 dma_intr;
- int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
- int dma_mask = ap->port_no ? ARTTIM2 : CFR;
+ int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+ int dma_reg = ap->port_no ? ARTTIM2 : CFR;
ata_bmdma_stop(qc);
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 1c628014dae..b1ca207e354 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -372,7 +372,8 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int cs5530_reinit_one(struct pci_dev *pdev)
{
/* If we fail on resume we are doomed */
- BUG_ON(cs5530_init_chip());
+ if (cs5530_init_chip())
+ BUG();
return ata_pci_device_resume(pdev);
}
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 47082df7199..dfb306057cf 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.5.1"
+#define DRV_VERSION "0.5.2"
struct hpt_clock {
u8 xfer_speed;
@@ -416,7 +416,7 @@ static const char *bad_ata100_5[] = {
static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
- if (adev->class != ATA_DEV_ATA) {
+ if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
@@ -749,7 +749,7 @@ static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int mscreg = 0x50 + 2 * ap->port_no;
+ int mscreg = 0x50 + 4 * ap->port_no;
u8 bwsr_stat, msc_stat;
pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index f6817b4093a..886fab9aa62 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n"
-#define DRV_VERSION "0.3"
+#define DRV_VERSION "0.3.2"
enum {
HPT_PCI_FAST = (1 << 31),
@@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap)
return 0;
}
-static int hpt3x2n_use_dpll(struct ata_port *ap, int reading)
+static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
{
long flags = (long)ap->host->private_data;
/* See if we should use the DPLL */
- if (reading == 0)
+ if (writing)
return USE_DPLL; /* Needed for write */
if (flags & PCI66)
return USE_DPLL; /* Needed at 66Mhz */
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 0b56ff3d1cf..e8afd486434 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
/**
* it821x_smart_set_mode - mode setting
* @ap: interface to set up
+ * @unused: device that failed (error only)
*
* Use a non standard set_mode function. We don't want to be tuned.
* The BIOS configured everything. Our job is not to fiddle. We
@@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
* and respect them.
*/
-static void it821x_smart_set_mode(struct ata_port *ap)
+static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int dma_enabled = 0;
int i;
@@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap)
}
}
}
+ return 0;
}
/**
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index cb8924109f5..23b8aab3ebd 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -23,9 +23,9 @@
#include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf"
-#define DRV_VERSION "0.1.1"
+#define DRV_VERSION "0.1.1ac1"
-static void ixp4xx_set_mode(struct ata_port *ap)
+static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev)
{
int i;
@@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
static void ixp4xx_phy_reset(struct ata_port *ap)
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 2d661cb4df3..d50264af284 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -204,20 +204,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
u32 reg;
- if (id->driver_data != 368) {
- /* Put the controller into AHCI mode in case the AHCI driver
- has not yet been loaded. This can be done with either
- function present */
+ /* PATA controller is fn 1, AHCI is fn 0 */
+ if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1)
+ return -ENODEV;
- /* FIXME: We may want a way to override this in future */
- pci_write_config_byte(pdev, 0x41, 0xa1);
-
- /* PATA controller is fn 1, AHCI is fn 0 */
- if (PCI_FUNC(pdev->devfn) != 1)
- return -ENODEV;
- }
- if ( id->driver_data == 365 || id->driver_data == 366) {
- /* The 365/66 have two PATA channels, redirect the second */
+ /* The 365/66 have two PATA channels, redirect the second */
+ if (id->driver_data == 365 || id->driver_data == 366) {
pci_read_config_dword(pdev, 0x80, &reg);
reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
pci_write_config_dword(pdev, 0x80, reg);
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index c7d1738e4e6..581cb33c6f4 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */
/**
* legacy_set_mode - mode setting
* @ap: IDE interface
+ * @unused: Device that failed when error is returned
*
* Use a non standard set_mode function. We don't want to be tuned.
*
@@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */
* expand on this as per hdparm in the base kernel.
*/
-static void legacy_set_mode(struct ata_port *ap)
+static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int i;
@@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
static struct scsi_host_template legacy_sht = {
@@ -698,8 +700,10 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
goto fail_io;
pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
- if (pdev == NULL)
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
goto fail_dev;
+ }
if (ht6560a & mask) {
ops = &ht6560a_port_ops;
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 443b1d85c6c..40ae11cbfda 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -30,7 +30,7 @@ static int pio_mask = 1;
* Provide our own set_mode() as we don't want to change anything that has
* already been configured..
*/
-static void pata_platform_set_mode(struct ata_port *ap)
+static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int i;
@@ -44,6 +44,7 @@ static void pata_platform_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
static void pata_platform_host_stop(struct ata_host *host)
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 36f621abc39..afc0d990e7d 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -247,8 +247,8 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
*/
pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 3677c642c9f..cec0729225e 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap)
/**
* rz1000_set_mode - mode setting function
* @ap: ATA interface
+ * @unused: returned device on set_mode failure
*
* Use a non standard set_mode function. We don't want to be tuned. We
* would prefer to be BIOS generic but for the fact our hardware is
* whacked out.
*/
-static void rz1000_set_mode(struct ata_port *ap)
+static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_enabled(dev)) {
+ if (ata_dev_ready(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
@@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
@@ -105,8 +107,6 @@ static struct ata_port_operations rz1000_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .error_handler = rz1000_error_handler,
-
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 32cf0bfa892..e8dfd8fc3ff 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -135,7 +135,7 @@ static void sil680_error_handler(struct ata_port *ap)
static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
- static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 };
+ static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };
unsigned long tfaddr = sil680_selreg(ap, 0x02);
unsigned long addr = sil680_seldev(ap, adev, 0x04);
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index cc09d47fb92..f0b6c3b7142 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -23,6 +23,7 @@
* VIA VT8233c - UDMA100
* VIA VT8235 - UDMA133
* VIA VT8237 - UDMA133
+ * VIA VT8237S - UDMA133
* VIA VT8251 - UDMA133
*
* Most registers remain compatible across chips. Others start reserved
@@ -61,7 +62,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_via"
-#define DRV_VERSION "0.2.0"
+#define DRV_VERSION "0.2.1"
/*
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -95,6 +96,7 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
@@ -161,10 +163,15 @@ static int via_pre_reset(struct ata_port *ap)
return -ENOENT;
}
- if ((config->flags & VIA_UDMA) >= VIA_UDMA_66)
+ if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
ap->cbl = via_cable_detect(ap);
- else
+ /* The UDMA66 series has no cable detect so do drive side detect */
+ else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
ap->cbl = ATA_CBL_PATA40;
+ else
+ ap->cbl = ATA_CBL_PATA_UNK;
+
+
return ata_std_prereset(ap);
}
@@ -390,7 +397,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
enable &= 3;
if (flags & VIA_SET_FIFO) {
- u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
+ static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
u8 fifo;
pci_read_config_byte(pdev, 0x43, &fifo);
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 3ea345cde52..5d1f518e1cc 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -206,8 +206,8 @@ static __init int winbond_init_one(unsigned long port)
*/
pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 1b8e0eb9e03..aae0b5201c1 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -523,8 +523,7 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_7042 */
.sht = &mv_sht,
- .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- MV_FLAG_DUAL_HC),
+ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_iie_ops,
@@ -545,6 +544,8 @@ static const struct pci_device_id mv_pci_tbl[] = {
{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+ { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+
{ } /* terminate list */
};
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0d316eb3c21..f7a963eb1f0 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -270,14 +270,6 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
- { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@@ -708,7 +700,6 @@ static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
- int handled;
/* freeze if hotplugged */
if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) {
@@ -727,13 +718,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
}
/* handle interrupt */
- handled = ata_host_intr(ap, qc);
- if (unlikely(!handled)) {
- /* spurious, clear it */
- ata_check_status(ap);
- }
-
- return 1;
+ return ata_host_intr(ap, qc);
}
static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -760,6 +745,11 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
>> (NV_INT_PORT_SHIFT * i);
+ if(ata_tag_valid(ap->active_tag))
+ /** NV_INT_DEV indication seems unreliable at times
+ at least in ADMA mode. Force it on always when a
+ command is active, to prevent losing interrupts. */
+ irq_stat |= NV_INT_DEV;
handled += nv_host_intr(ap, irq_stat);
continue;
}
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index db32d15b7fa..46d8a94669b 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -56,6 +56,8 @@
#define DRV_VERSION "2.0"
enum {
+ K2_FLAG_NO_ATAPI_DMA = (1 << 29),
+
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
K2_SATA_TF_DATA_OFFSET = 0x00,
@@ -83,11 +85,33 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
+
+ board_svw4 = 0,
+ board_svw8 = 1,
+};
+
+static const struct k2_board_info {
+ unsigned int n_ports;
+ unsigned long port_flags;
+} k2_board_info[] = {
+ /* board_svw4 */
+ { 4, K2_FLAG_NO_ATAPI_DMA },
+
+ /* board_svw8 */
+ { 8, K2_FLAG_NO_ATAPI_DMA },
};
static u8 k2_stat_check_status(struct ata_port *ap);
+static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
+ return -1; /* ATAPI DMA not supported */
+
+ return 0;
+}
+
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
@@ -111,26 +135,31 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
if (tf->ctl != ap->last_ctl) {
- writeb(tf->ctl, ioaddr->ctl_addr);
+ writeb(tf->ctl, (void __iomem *) ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ (void __iomem *) ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, ioaddr->feature_addr);
- writew(tf->nsect, ioaddr->nsect_addr);
- writew(tf->lbal, ioaddr->lbal_addr);
- writew(tf->lbam, ioaddr->lbam_addr);
- writew(tf->lbah, ioaddr->lbah_addr);
+ writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, ioaddr->device_addr);
+ writeb(tf->device, (void __iomem *) ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -142,12 +171,12 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = k2_stat_check_status(ap);
- tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
- nsect = readw(ioaddr->nsect_addr);
- lbal = readw(ioaddr->lbal_addr);
- lbam = readw(ioaddr->lbam_addr);
- lbah = readw(ioaddr->lbah_addr);
+ tf->device = readw((void __iomem *)ioaddr->device_addr);
+ feature = readw((void __iomem *)ioaddr->error_addr);
+ nsect = readw((void __iomem *)ioaddr->nsect_addr);
+ lbal = readw((void __iomem *)ioaddr->lbal_addr);
+ lbam = readw((void __iomem *)ioaddr->lbam_addr);
+ lbah = readw((void __iomem *)ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -313,6 +342,7 @@ static const struct ata_port_operations k2_sata_ops = {
.check_status = k2_stat_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = k2_sata_check_atapi_dma,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
.bmdma_stop = ata_bmdma_stop,
@@ -359,6 +389,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
void __iomem *mmio_base;
+ const struct k2_board_info *board_info =
+ &k2_board_info[ent->driver_data];
int pci_dev_busy = 0;
int rc;
int i;
@@ -424,7 +456,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->sht = &k2_sata_sht;
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO;
+ ATA_FLAG_MMIO | board_info->port_flags;
probe_ent->port_ops = &k2_sata_ops;
probe_ent->n_ports = 4;
probe_ent->irq = pdev->irq;
@@ -441,7 +473,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
* longer available. This should not be seen in any system. */
- for (i = 0; i < ent->driver_data; i++)
+ for (i = 0; i < board_info->n_ports; i++)
k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
pci_set_master(pdev);
@@ -469,11 +501,11 @@ err_out:
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
{ }
};
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 5c603ca3a50..a43aec62d50 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = {
static struct ata_port_info uli_port_info = {
.sht = &uli_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_IGN_SIMPLEX,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &uli_ops,
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1c7f19aecc2..d3d5c0d5703 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -74,9 +74,11 @@ enum {
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static void svia_noop_freeze(struct ata_port *ap);
static void vt6420_error_handler(struct ata_port *ap);
static const struct pci_device_id svia_pci_tbl[] = {
+ { PCI_VDEVICE(VIA, 0x5337), vt6420 },
{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
@@ -127,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = {
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_pio_data_xfer,
- .freeze = ata_bmdma_freeze,
+ .freeze = svia_noop_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = vt6420_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
@@ -203,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
outl(val, ap->ioaddr.scr_addr + (4 * sc_reg));
}
+static void svia_noop_freeze(struct ata_port *ap)
+{
+ /* Some VIA controllers choke if ATA_NIEN is manipulated in
+ * certain way. Leave it alone and just clear pending IRQ.
+ */
+ ata_chk_status(ap);
+ ata_bmdma_irq_clear(ap);
+}
+
/**
* vt6420_prereset - prereset for vt6420
* @ap: target ATA port
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index e654b990b90..0fa1b89f76d 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -149,21 +149,26 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ (void __iomem *) ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, ioaddr->feature_addr);
- writew(tf->nsect, ioaddr->nsect_addr);
- writew(tf->lbal, ioaddr->lbal_addr);
- writew(tf->lbam, ioaddr->lbam_addr);
- writew(tf->lbah, ioaddr->lbah_addr);
+ writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, ioaddr->device_addr);
+ writeb(tf->device, (void __iomem *) ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -175,12 +180,12 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = ata_check_status(ap);
- tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
- nsect = readw(ioaddr->nsect_addr);
- lbal = readw(ioaddr->lbal_addr);
- lbam = readw(ioaddr->lbam_addr);
- lbah = readw(ioaddr->lbah_addr);
+ tf->device = readw((void __iomem *) ioaddr->device_addr);
+ feature = readw((void __iomem *) ioaddr->error_addr);
+ nsect = readw((void __iomem *) ioaddr->nsect_addr);
+ lbal = readw((void __iomem *) ioaddr->lbal_addr);
+ lbam = readw((void __iomem *) ioaddr->lbam_addr);
+ lbah = readw((void __iomem *) ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -327,8 +332,8 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned lon
port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET;
port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET;
port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET;
- writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
- writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
+ writel(0, (void __iomem *) base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
+ writel(0, (void __iomem *) base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
}