diff options
Diffstat (limited to 'drivers/ata')
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, ®D); pci_read_config_byte(pdev, pciU, ®U); - 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 |= (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); } |