summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch')
-rw-r--r--openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch9939
1 files changed, 0 insertions, 9939 deletions
diff --git a/openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch b/openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch
deleted file mode 100644
index b3c2d6f..0000000
--- a/openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch
+++ /dev/null
@@ -1,9939 +0,0 @@
---- ./drivers/scsi/Makefile.libata 2004-08-14 14:55:59.000000000 +0400
-+++ ./drivers/scsi/Makefile 2005-11-14 17:07:38.175257768 +0300
-@@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o
- obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
- obj-$(CONFIG_SCSI_NSP32) += nsp32.o
- obj-$(CONFIG_SCSI_IPR) += ipr.o
-+obj-$(CONFIG_SCSI_AHCI) += ahci.o
- obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o
- obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
- obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
-@@ -156,7 +156,7 @@ zalon7xx-objs := zalon.o ncr53c8xx.o
- NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
- cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
- cpqfcTSworker.o cpqfcTStrigger.o
--libata-objs := libata-core.o libata-scsi.o
-+libata-objs := libata-core.o libata-scsi.o libata-dump.o
-
- # Files generated that shall be removed upon make clean
- clean-files := 53c7xx_d.h 53c700_d.h \
---- ./drivers/scsi/sata_promise.c.libata 2005-09-26 13:33:14.000000000 +0400
-+++ ./drivers/scsi/sata_promise.c 2005-10-26 14:55:16.999916400 +0400
-@@ -40,7 +40,7 @@
- #include "sata_promise.h"
-
- #define DRV_NAME "sata_promise"
--#define DRV_VERSION "1.00"
-+#define DRV_VERSION "1.01"
-
-
- enum {
-@@ -59,6 +59,7 @@ enum {
-
- board_2037x = 0, /* FastTrak S150 TX2plus */
- board_20319 = 1, /* FastTrak S150 TX4 */
-+ board_20619 = 2, /* FastTrak TX4000 */
-
- PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */
-
-@@ -73,8 +74,7 @@ struct pdc_port_priv {
-
- static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
- static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
--static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
--static void pdc_dma_start(struct ata_queued_cmd *qc);
-+static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
- static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
- static void pdc_eng_timeout(struct ata_port *ap);
- static int pdc_port_start(struct ata_port *ap);
-@@ -83,14 +83,13 @@ static void pdc_phy_reset(struct ata_por
- static void pdc_qc_prep(struct ata_queued_cmd *qc);
- static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
- static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
--static inline void pdc_dma_complete (struct ata_port *ap,
-- struct ata_queued_cmd *qc, int have_err);
- static void pdc_irq_clear(struct ata_port *ap);
- static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
-
--static Scsi_Host_Template pdc_sata_sht = {
-+static Scsi_Host_Template pdc_ata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -104,14 +103,18 @@ static Scsi_Host_Template pdc_sata_sht =
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .bios_param = ata_std_bios_param,
-+ .dump_sanity_check = ata_scsi_dump_sanity_check,
-+ .dump_quiesce = ata_scsi_dump_quiesce,
-+ .dump_poll = ata_scsi_dump_poll,
- };
-
--static struct ata_port_operations pdc_sata_ops = {
-+static struct ata_port_operations pdc_ata_ops = {
- .port_disable = ata_port_disable,
- .tf_load = pdc_tf_load_mmio,
-- .tf_read = ata_tf_read_mmio,
-- .check_status = ata_check_status_mmio,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = pdc_phy_reset,
- .qc_prep = pdc_qc_prep,
- .qc_issue = pdc_qc_issue_prot,
-@@ -122,58 +125,85 @@ static struct ata_port_operations pdc_sa
- .scr_write = pdc_sata_scr_write,
- .port_start = pdc_port_start,
- .port_stop = pdc_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static struct ata_port_info pdc_port_info[] = {
- /* board_2037x */
- {
-- .sht = &pdc_sata_sht,
-+ .sht = &pdc_ata_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SRST | ATA_FLAG_MMIO,
-- .pio_mask = 0x03, /* pio3-4 */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-- .port_ops = &pdc_sata_ops,
-+ .port_ops = &pdc_ata_ops,
- },
-
- /* board_20319 */
- {
-- .sht = &pdc_sata_sht,
-+ .sht = &pdc_ata_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SRST | ATA_FLAG_MMIO,
-- .pio_mask = 0x03, /* pio3-4 */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-- .port_ops = &pdc_sata_ops,
-+ .port_ops = &pdc_ata_ops,
-+ },
-+
-+ /* board_20619 */
-+ {
-+ .sht = &pdc_ata_sht,
-+ .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
-+ ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS,
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-+ .port_ops = &pdc_ata_ops,
- },
- };
-
--static struct pci_device_id pdc_sata_pci_tbl[] = {
-+static struct pci_device_id pdc_ata_pci_tbl[] = {
- { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_2037x },
-+ { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_2037x },
- { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_2037x },
- { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_2037x },
- { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_2037x },
-+ { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_2037x },
-+ { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_2037x },
-+
- { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_20319 },
- { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- board_20319 },
-+ { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_20319 },
-+
-+ { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_20619 },
-+
- { } /* terminate list */
- };
-
-
--static struct pci_driver pdc_sata_pci_driver = {
-+static struct pci_driver pdc_ata_pci_driver = {
- .name = DRV_NAME,
-- .id_table = pdc_sata_pci_tbl,
-- .probe = pdc_sata_init_one,
-+ .id_table = pdc_ata_pci_tbl,
-+ .probe = pdc_ata_init_one,
- .remove = ata_pci_remove_one,
- };
-
-
- static int pdc_port_start(struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
- struct pdc_port_priv *pp;
- int rc;
-
-@@ -188,7 +218,7 @@ static int pdc_port_start(struct ata_por
- }
- memset(pp, 0, sizeof(*pp));
-
-- pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
-+ pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
-@@ -208,11 +238,11 @@ err_out:
-
- static void pdc_port_stop(struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
-- pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
-+ dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
- }
-@@ -269,26 +299,26 @@ static void pdc_qc_prep(struct ata_queue
-
- VPRINTK("ENTER\n");
-
-- ata_qc_prep(qc);
--
-- i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, qc->dev->devno, pp->pkt);
-+ switch (qc->tf.protocol) {
-+ case ATA_PROT_DMA:
-+ ata_qc_prep(qc);
-+ /* fall through */
-
-- if (qc->tf.flags & ATA_TFLAG_LBA48)
-- i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
-- else
-- i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
-+ case ATA_PROT_NODATA:
-+ i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,
-+ qc->dev->devno, pp->pkt);
-
-- pdc_pkt_footer(&qc->tf, pp->pkt, i);
--}
-+ if (qc->tf.flags & ATA_TFLAG_LBA48)
-+ i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
-+ else
-+ i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
-
--static inline void pdc_dma_complete (struct ata_port *ap,
-- struct ata_queued_cmd *qc,
-- int have_err)
--{
-- u8 err_bit = have_err ? ATA_ERR : 0;
-+ pdc_pkt_footer(&qc->tf, pp->pkt, i);
-+ break;
-
-- /* get drive status; clear intr; complete txn */
-- ata_qc_complete(qc, ata_wait_idle(ap) | err_bit);
-+ default:
-+ break;
-+ }
- }
-
- static void pdc_eng_timeout(struct ata_port *ap)
-@@ -315,17 +345,9 @@ static void pdc_eng_timeout(struct ata_p
-
- switch (qc->tf.protocol) {
- case ATA_PROT_DMA:
-- printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
-- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
-- break;
--
- case ATA_PROT_NODATA:
-- drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
--
-- printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n",
-- ap->id, qc->tf.command, drv_stat);
--
-- ata_qc_complete(qc, drv_stat);
-+ printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-+ ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
- break;
-
- default:
-@@ -358,13 +380,8 @@ static inline unsigned int pdc_host_intr
-
- switch (qc->tf.protocol) {
- case ATA_PROT_DMA:
-- pdc_dma_complete(ap, qc, have_err);
-- handled = 1;
-- break;
--
-- case ATA_PROT_NODATA: /* command completion, but no data xfer */
-- status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
-- DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
-+ case ATA_PROT_NODATA:
-+ status = ata_wait_idle(ap);
- if (have_err)
- status |= ATA_ERR;
- ata_qc_complete(qc, status);
-@@ -418,9 +435,11 @@ static irqreturn_t pdc_interrupt (int ir
- return IRQ_NONE;
- }
-
-- spin_lock(&host_set->lock);
-+ spin_lock(&host_set->lock);
-+
-+ writel(mask, mmio_base + PDC_INT_SEQMASK);
-
-- for (i = 0; i < host_set->n_ports; i++) {
-+ for (i = 0; i < host_set->n_ports; i++) {
- VPRINTK("port %u\n", i);
- ap = host_set->ports[i];
- tmp = mask & (1 << (i + 1));
-@@ -440,7 +459,7 @@ static irqreturn_t pdc_interrupt (int ir
- return IRQ_RETVAL(handled);
- }
-
--static inline void pdc_dma_start(struct ata_queued_cmd *qc)
-+static inline void pdc_packet_start(struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- struct pdc_port_priv *pp = ap->private_data;
-@@ -462,7 +481,8 @@ static int pdc_qc_issue_prot(struct ata_
- {
- switch (qc->tf.protocol) {
- case ATA_PROT_DMA:
-- pdc_dma_start(qc);
-+ case ATA_PROT_NODATA:
-+ pdc_packet_start(qc);
- return 0;
-
- case ATA_PROT_ATAPI_DMA:
-@@ -478,19 +498,21 @@ static int pdc_qc_issue_prot(struct ata_
-
- static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
-- WARN_ON (tf->protocol == ATA_PROT_DMA);
-- ata_tf_load_mmio(ap, tf);
-+ WARN_ON (tf->protocol == ATA_PROT_DMA ||
-+ tf->protocol == ATA_PROT_NODATA);
-+ ata_tf_load(ap, tf);
- }
-
-
- static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
-- WARN_ON (tf->protocol == ATA_PROT_DMA);
-- ata_exec_command_mmio(ap, tf);
-+ WARN_ON (tf->protocol == ATA_PROT_DMA ||
-+ tf->protocol == ATA_PROT_NODATA);
-+ ata_exec_command(ap, tf);
- }
-
-
--static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
-+static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
- {
- port->cmd_addr = base;
- port->data_addr = base;
-@@ -539,8 +561,7 @@ static void pdc_host_init(unsigned int c
- writel(tmp, mmio + PDC_TBG_MODE);
-
- readl(mmio + PDC_TBG_MODE); /* flush */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(msecs_to_jiffies(10) + 1);
-+ msleep(10);
-
- /* adjust slew rate control register. */
- tmp = readl(mmio + PDC_SLEW_CTL);
-@@ -549,13 +570,14 @@ static void pdc_host_init(unsigned int c
- writel(tmp, mmio + PDC_SLEW_CTL);
- }
-
--static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-+static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
- {
- static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
- void *mmio_base;
- unsigned int board_idx = (unsigned int) ent->driver_data;
-+ int pci_dev_busy = 0;
- int rc;
-
- if (!printed_version++)
-@@ -570,8 +592,10 @@ static int pdc_sata_init_one (struct pci
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -587,7 +611,7 @@ static int pdc_sata_init_one (struct pci
- }
-
- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-+ probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- mmio_base = ioremap(pci_resource_start(pdev, 3),
-@@ -601,6 +625,7 @@ static int pdc_sata_init_one (struct pci
- probe_ent->sht = pdc_port_info[board_idx].sht;
- probe_ent->host_flags = pdc_port_info[board_idx].host_flags;
- probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
-+ probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
- probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
-
-@@ -608,8 +633,8 @@ static int pdc_sata_init_one (struct pci
- probe_ent->irq_flags = SA_SHIRQ;
- probe_ent->mmio_base = mmio_base;
-
-- pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
-- pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
-+ pdc_ata_setup_port(&probe_ent->port[0], base + 0x200);
-+ pdc_ata_setup_port(&probe_ent->port[1], base + 0x280);
-
- probe_ent->port[0].scr_addr = base + 0x400;
- probe_ent->port[1].scr_addr = base + 0x500;
-@@ -619,8 +644,8 @@ static int pdc_sata_init_one (struct pci
- case board_20319:
- probe_ent->n_ports = 4;
-
-- pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-- pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
-+ pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
-+ pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
-
- probe_ent->port[2].scr_addr = base + 0x600;
- probe_ent->port[3].scr_addr = base + 0x700;
-@@ -628,6 +653,15 @@ static int pdc_sata_init_one (struct pci
- case board_2037x:
- probe_ent->n_ports = 2;
- break;
-+ case board_20619:
-+ probe_ent->n_ports = 4;
-+
-+ pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
-+ pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
-+
-+ probe_ent->port[2].scr_addr = base + 0x600;
-+ probe_ent->port[3].scr_addr = base + 0x700;
-+ break;
- default:
- BUG();
- break;
-@@ -649,27 +683,29 @@ err_out_free_ent:
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
-
--static int __init pdc_sata_init(void)
-+static int __init pdc_ata_init(void)
- {
-- return pci_module_init(&pdc_sata_pci_driver);
-+ return pci_module_init(&pdc_ata_pci_driver);
- }
-
-
--static void __exit pdc_sata_exit(void)
-+static void __exit pdc_ata_exit(void)
- {
-- pci_unregister_driver(&pdc_sata_pci_driver);
-+ pci_unregister_driver(&pdc_ata_pci_driver);
- }
-
-
- MODULE_AUTHOR("Jeff Garzik");
--MODULE_DESCRIPTION("Promise SATA TX2/TX4 low-level driver");
-+MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver");
- MODULE_LICENSE("GPL");
--MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
-+MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
--module_init(pdc_sata_init);
--module_exit(pdc_sata_exit);
-+module_init(pdc_ata_init);
-+module_exit(pdc_ata_exit);
---- ./drivers/scsi/ata_piix.c.libata 2005-09-26 13:33:13.000000000 +0400
-+++ ./drivers/scsi/ata_piix.c 2005-10-26 14:55:16.991917616 +0400
-@@ -32,13 +32,15 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "ata_piix"
--#define DRV_VERSION "1.02"
-+#define DRV_VERSION "1.03"
-
- enum {
- PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
- ICH5_PMR = 0x90, /* port mapping register */
- ICH5_PCS = 0x92, /* port control and status */
-+ PIIX_SCC = 0x0A, /* sub-class code register */
-
-+ PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */
- PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */
- PIIX_FLAG_COMBINED = (1 << 30), /* combined mode possible */
-
-@@ -58,6 +60,11 @@ enum {
- ich5_sata = 1,
- piix4_pata = 2,
- ich6_sata = 3,
-+ ich6_sata_rm = 4,
-+ ich7_sata = 5,
-+ esb2_sata = 6,
-+
-+ PIIX_AHCI_DEVICE = 6,
- };
-
- static int piix_init_one (struct pci_dev *pdev,
-@@ -65,10 +72,8 @@ static int piix_init_one (struct pci_dev
-
- static void piix_pata_phy_reset(struct ata_port *ap);
- static void piix_sata_phy_reset(struct ata_port *ap);
--static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
-- unsigned int pio);
--static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
-- unsigned int udma);
-+static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
-+static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
-
- static unsigned int in_module_init = 1;
-
-@@ -87,13 +92,12 @@ static struct pci_device_id piix_pci_tbl
- { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
- { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
- { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
--
-- /* ICH6 operates in two modes, "looks-like-ICH5" mode,
-- * and enhanced mode, with queueing and other fancy stuff.
-- * This is distinguished by PCI class code.
-- */
- { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
-- { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
-+ { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-+ { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-+ { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-+ { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-+ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
-
- { } /* terminate list */
- };
-@@ -108,6 +112,7 @@ static struct pci_driver piix_pci_driver
- static Scsi_Host_Template piix_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -121,22 +126,28 @@ static Scsi_Host_Template piix_sht = {
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .bios_param = ata_std_bios_param,
-+ .dump_sanity_check = ata_scsi_dump_sanity_check,
-+ .dump_quiesce = ata_scsi_dump_quiesce,
-+ .dump_poll = ata_scsi_dump_poll,
- };
-
- static struct ata_port_operations piix_pata_ops = {
- .port_disable = ata_port_disable,
- .set_piomode = piix_set_piomode,
-- .set_udmamode = piix_set_udmamode,
-+ .set_dmamode = piix_set_dmamode,
-
-- .tf_load = ata_tf_load_pio,
-- .tf_read = ata_tf_read_pio,
-- .check_status = ata_check_status_pio,
-- .exec_command = ata_exec_command_pio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
-
- .phy_reset = piix_pata_phy_reset,
-
-- .bmdma_setup = ata_bmdma_setup_pio,
-- .bmdma_start = ata_bmdma_start_pio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
-@@ -147,22 +158,24 @@ static struct ata_port_operations piix_p
-
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static struct ata_port_operations piix_sata_ops = {
- .port_disable = ata_port_disable,
-- .set_piomode = piix_set_piomode,
-- .set_udmamode = piix_set_udmamode,
-
-- .tf_load = ata_tf_load_pio,
-- .tf_read = ata_tf_read_pio,
-- .check_status = ata_check_status_pio,
-- .exec_command = ata_exec_command_pio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
-
- .phy_reset = piix_sata_phy_reset,
-
-- .bmdma_setup = ata_bmdma_setup_pio,
-- .bmdma_start = ata_bmdma_start_pio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
-@@ -173,6 +186,7 @@ static struct ata_port_operations piix_s
-
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static struct ata_port_info piix_port_info[] = {
-@@ -181,8 +195,13 @@ static struct ata_port_info piix_port_in
- .sht = &piix_sht,
- .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
- PIIX_FLAG_CHECKINTR,
-- .pio_mask = 0x03, /* pio3-4 */
-- .udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+#if 0
-+ .mwdma_mask = 0x06, /* mwdma1-2 */
-+#else
-+ .mwdma_mask = 0x00, /* mwdma broken */
-+#endif
-+ .udma_mask = 0x3f, /* udma0-5 */
- .port_ops = &piix_pata_ops,
- },
-
-@@ -191,8 +210,9 @@ static struct ata_port_info piix_port_in
- .sht = &piix_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
- PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
-- .pio_mask = 0x03, /* pio3-4 */
-- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 */
- .port_ops = &piix_sata_ops,
- },
-
-@@ -200,8 +220,13 @@ static struct ata_port_info piix_port_in
- {
- .sht = &piix_sht,
- .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
-- .pio_mask = 0x03, /* pio3-4 */
-- .udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+#if 0
-+ .mwdma_mask = 0x06, /* mwdma1-2 */
-+#else
-+ .mwdma_mask = 0x00, /* mwdma broken */
-+#endif
-+ .udma_mask = ATA_UDMA_MASK_40C,
- .port_ops = &piix_pata_ops,
- },
-
-@@ -211,8 +236,45 @@ static struct ata_port_info piix_port_in
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
- PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
- ATA_FLAG_SLAVE_POSS,
-- .pio_mask = 0x03, /* pio3-4 */
-- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 */
-+ .port_ops = &piix_sata_ops,
-+ },
-+
-+ /* ich6_sata_rm */
-+ {
-+ .sht = &piix_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
-+ PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-+ ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 */
-+ .port_ops = &piix_sata_ops,
-+ },
-+
-+ /* ich7_sata */
-+ {
-+ .sht = &piix_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
-+ PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-+ ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 */
-+ .port_ops = &piix_sata_ops,
-+ },
-+
-+ /* esb2_sata */
-+ {
-+ .sht = &piix_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
-+ PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-+ ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-6 */
- .port_ops = &piix_sata_ops,
- },
- };
-@@ -226,12 +288,13 @@ MODULE_AUTHOR("Andre Hedrick, Alan Cox,
- MODULE_DESCRIPTION("SCSI low-level driver for Intel PIIX/ICH ATA controllers");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- /**
- * piix_pata_cbl_detect - Probe host controller cable detect info
- * @ap: Port for which cable detect info is desired
- *
-- * Read 80c cable indicator from SATA PCI device's PCI config
-+ * Read 80c cable indicator from ATA PCI device's PCI config
- * register. This register is normally set by firmware (BIOS).
- *
- * LOCKING:
-@@ -239,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
- */
- static void piix_pata_cbl_detect(struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- u8 tmp, mask;
-
- /* no 80c support in host controller? */
-@@ -247,7 +310,7 @@ static void piix_pata_cbl_detect(struct
- goto cbl40;
-
- /* check BIOS cable detect results */
-- mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
-+ mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
- pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
- if ((tmp & mask) == 0)
- goto cbl40;
-@@ -272,8 +335,9 @@ cbl40:
-
- static void piix_pata_phy_reset(struct ata_port *ap)
- {
-- if (!pci_test_config_bits(ap->host_set->pdev,
-- &piix_enable_bits[ap->port_no])) {
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-+
-+ if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
- ata_port_disable(ap);
- printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
- return;
-@@ -301,13 +365,13 @@ static void piix_pata_phy_reset(struct a
- */
- static int piix_sata_probe (struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
- int orig_mask, mask, i;
- u8 pcs;
-
-- mask = (PIIX_PORT_PRESENT << ap->port_no) |
-- (PIIX_PORT_ENABLED << ap->port_no);
-+ mask = (PIIX_PORT_PRESENT << ap->hard_port_no) |
-+ (PIIX_PORT_ENABLED << ap->hard_port_no);
-
- pci_read_config_byte(pdev, ICH5_PCS, &pcs);
- orig_mask = (int) pcs & 0xff;
-@@ -324,7 +388,7 @@ static int piix_sata_probe (struct ata_p
- mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i);
-
- if ((orig_mask & mask) == mask)
-- if (combined || (i == ap->port_no))
-+ if (combined || (i == ap->hard_port_no))
- return 1;
- }
-
-@@ -368,12 +432,12 @@ static void piix_sata_phy_reset(struct a
- * None (inherited from caller).
- */
-
--static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
-- unsigned int pio)
-+static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
- {
-- struct pci_dev *dev = ap->host_set->pdev;
-- unsigned int is_slave = (adev->flags & ATA_DFLAG_MASTER) ? 0 : 1;
-- unsigned int master_port= ap->port_no ? 0x42 : 0x40;
-+ unsigned int pio = adev->pio_mode - XFER_PIO_0;
-+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev);
-+ unsigned int is_slave = (adev->devno != 0);
-+ unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
- unsigned int slave_port = 0x44;
- u16 master_data;
- u8 slave_data;
-@@ -391,10 +455,10 @@ static void piix_set_piomode (struct ata
- /* enable PPE, IE and TIME */
- master_data |= 0x0070;
- pci_read_config_byte(dev, slave_port, &slave_data);
-- slave_data &= (ap->port_no ? 0x0f : 0xf0);
-+ slave_data &= (ap->hard_port_no ? 0x0f : 0xf0);
- slave_data |=
- (timings[pio][0] << 2) |
-- (timings[pio][1] << (ap->port_no ? 4 : 0));
-+ (timings[pio][1] << (ap->hard_port_no ? 4 : 0));
- } else {
- master_data &= 0xccf8;
- /* enable PPE, IE and TIME */
-@@ -409,7 +473,7 @@ static void piix_set_piomode (struct ata
- }
-
- /**
-- * piix_set_udmamode - Initialize host controller PATA PIO timings
-+ * piix_set_dmamode - Initialize host controller PATA PIO timings
- * @ap: Port whose timings we are configuring
- * @adev: um
- * @udma: udma mode, 0 - 6
-@@ -420,13 +484,13 @@ static void piix_set_piomode (struct ata
- * None (inherited from caller).
- */
-
--static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
-- unsigned int udma)
-+static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
- {
-- struct pci_dev *dev = ap->host_set->pdev;
-- u8 maslave = ap->port_no ? 0x42 : 0x40;
-+ unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */
-+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev);
-+ u8 maslave = ap->hard_port_no ? 0x42 : 0x40;
- u8 speed = udma;
-- unsigned int drive_dn = (ap->port_no ? 2 : 0) + adev->devno;
-+ unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno;
- int a_speed = 3 << (drive_dn * 4);
- int u_flag = 1 << drive_dn;
- int v_flag = 0x01 << drive_dn;
-@@ -452,25 +516,38 @@ static void piix_set_udmamode (struct at
- case XFER_UDMA_3:
- case XFER_UDMA_1: u_speed = 1 << (drive_dn * 4); break;
- case XFER_UDMA_0: u_speed = 0 << (drive_dn * 4); break;
-+ case XFER_MW_DMA_2:
-+ case XFER_MW_DMA_1: break;
- default:
- BUG();
- return;
- }
-
-- if (!(reg48 & u_flag))
-- pci_write_config_byte(dev, 0x48, reg48 | u_flag);
-- if (speed == XFER_UDMA_5) {
-- pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
-+ if (speed >= XFER_UDMA_0) {
-+ if (!(reg48 & u_flag))
-+ pci_write_config_byte(dev, 0x48, reg48 | u_flag);
-+ if (speed == XFER_UDMA_5) {
-+ pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
-+ } else {
-+ pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
-+ }
-+ if ((reg4a & a_speed) != u_speed)
-+ pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
-+ if (speed > XFER_UDMA_2) {
-+ if (!(reg54 & v_flag))
-+ pci_write_config_byte(dev, 0x54, reg54 | v_flag);
-+ } else
-+ pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
- } else {
-- pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
-+ if (reg48 & u_flag)
-+ pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
-+ if (reg4a & a_speed)
-+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-+ if (reg54 & v_flag)
-+ pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
-+ if (reg55 & w_flag)
-+ pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
- }
-- if ((reg4a & a_speed) != u_speed)
-- pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
-- if (speed > XFER_UDMA_2) {
-- if (!(reg54 & v_flag))
-- pci_write_config_byte(dev, 0x54, reg54 | v_flag);
-- } else
-- pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
- }
-
- /* move to PCI layer, integrate w/ MSI stuff */
-@@ -485,6 +562,42 @@ static void pci_enable_intx(struct pci_d
- }
- }
-
-+#define AHCI_PCI_BAR 5
-+#define AHCI_GLOBAL_CTL 0x04
-+#define AHCI_ENABLE (1 << 31)
-+static int piix_disable_ahci(struct pci_dev *pdev)
-+{
-+ void *mmio;
-+ unsigned long addr;
-+ u32 tmp;
-+ int rc = 0;
-+
-+ /* BUG: pci_enable_device has not yet been called. This
-+ * works because this device is usually set up by BIOS.
-+ */
-+
-+ addr = pci_resource_start(pdev, AHCI_PCI_BAR);
-+ if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR))
-+ return 0;
-+
-+ mmio = ioremap(addr, 64);
-+ if (!mmio)
-+ return -ENOMEM;
-+
-+ tmp = readl(mmio + AHCI_GLOBAL_CTL);
-+ if (tmp & AHCI_ENABLE) {
-+ tmp &= ~AHCI_ENABLE;
-+ writel(tmp, mmio + AHCI_GLOBAL_CTL);
-+
-+ tmp = readl(mmio + AHCI_GLOBAL_CTL);
-+ if (tmp & AHCI_ENABLE)
-+ rc = -EIO;
-+ }
-+
-+ iounmap(mmio);
-+ return rc;
-+}
-+
- /**
- * piix_init_one - Register PIIX ATA PCI device with kernel services
- * @pdev: PCI device to register
-@@ -517,6 +630,16 @@ static int piix_init_one (struct pci_dev
- port_info[0] = &piix_port_info[ent->driver_data];
- port_info[1] = NULL;
-
-+ if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
-+ u8 tmp;
-+ pci_read_config_byte(pdev, PIIX_SCC, &tmp);
-+ if (tmp == PIIX_AHCI_DEVICE) {
-+ int rc = piix_disable_ahci(pdev);
-+ if (rc)
-+ return rc;
-+ }
-+ }
-+
- if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
- u8 tmp;
- pci_read_config_byte(pdev, ICH5_PMR, &tmp);
-@@ -551,15 +674,6 @@ static int piix_init_one (struct pci_dev
- return ata_pci_init_one(pdev, port_info, n_ports);
- }
-
--/**
-- * piix_init -
-- *
-- * LOCKING:
-- *
-- * RETURNS:
-- *
-- */
--
- static int __init piix_init(void)
- {
- int rc;
-@@ -575,13 +689,6 @@ static int __init piix_init(void)
- return 0;
- }
-
--/**
-- * piix_exit -
-- *
-- * LOCKING:
-- *
-- */
--
- static void __exit piix_exit(void)
- {
- pci_unregister_driver(&piix_pci_driver);
---- ./drivers/scsi/libata.h.libata 2005-09-26 13:33:13.000000000 +0400
-+++ ./drivers/scsi/libata.h 2005-10-26 14:55:16.989917920 +0400
-@@ -26,26 +26,29 @@
- #define __LIBATA_H__
-
- #define DRV_NAME "libata"
--#define DRV_VERSION "1.02" /* must be exactly four chars */
-+#define DRV_VERSION "1.11" /* must be exactly four chars */
-
- struct ata_scsi_args {
-- struct ata_port *ap;
-- struct ata_device *dev;
-- struct scsi_cmnd *cmd;
-+ u16 *id;
-+ struct scsi_cmnd *cmd;
- void (*done)(struct scsi_cmnd *);
- };
-
- /* libata-core.c */
- extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
- struct ata_device *dev);
-+extern void ata_qc_free(struct ata_queued_cmd *qc);
- extern int ata_qc_issue(struct ata_queued_cmd *qc);
-+extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
- extern void ata_dev_select(struct ata_port *ap, unsigned int device,
- unsigned int wait, unsigned int can_sleep);
- extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
-+extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
-+extern void ata_pio_task(void *_data);
-
-
- /* libata-scsi.c */
--extern void ata_to_sense_error(struct ata_queued_cmd *qc);
-+extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
- extern int ata_scsi_error(struct Scsi_Host *host);
- extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
- unsigned int buflen);
-@@ -73,6 +76,8 @@ extern void ata_scsi_badcmd(struct scsi_
- extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
- unsigned int (*actor) (struct ata_scsi_args *args,
- u8 *rbuf, unsigned int buflen));
-+extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
-+ struct scsi_device *scsidev);
-
- static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
- {
---- ./drivers/scsi/sata_vsc.c.libata 2005-09-26 13:33:14.000000000 +0400
-+++ ./drivers/scsi/sata_vsc.c 2005-10-26 14:55:16.994917160 +0400
-@@ -21,12 +21,13 @@
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
- #include "scsi.h"
- #include <scsi/scsi_host.h>
- #include <linux/libata.h>
-
- #define DRV_NAME "sata_vsc"
--#define DRV_VERSION "0.01"
-+#define DRV_VERSION "1.0"
-
- /* Interrupt register offsets (from chip base address) */
- #define VSC_SATA_INT_STAT_OFFSET 0x00
-@@ -155,7 +156,8 @@ static void vsc_sata_tf_read(struct ata_
- *
- * Read the interrupt register and process for the devices that have them pending.
- */
--irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
-+static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
-+ struct pt_regs *regs)
- {
- struct ata_host_set *host_set = dev_instance;
- unsigned int i;
-@@ -190,6 +192,7 @@ irqreturn_t vsc_sata_interrupt (int irq,
- static Scsi_Host_Template vsc_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -210,11 +213,14 @@ static struct ata_port_operations vsc_sa
- .port_disable = ata_port_disable,
- .tf_load = vsc_sata_tf_load,
- .tf_read = vsc_sata_tf_read,
-- .exec_command = ata_exec_command_mmio,
-- .check_status = ata_check_status_mmio,
-+ .exec_command = ata_exec_command,
-+ .check_status = ata_check_status,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = sata_phy_reset,
-- .bmdma_setup = ata_bmdma_setup_mmio,
-- .bmdma_start = ata_bmdma_start_mmio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
-@@ -224,6 +230,7 @@ static struct ata_port_operations vsc_sa
- .scr_write = vsc_sata_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
-@@ -253,6 +260,7 @@ static int __devinit vsc_sata_init_one (
- static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
-+ int pci_dev_busy = 0;
- void *mmio_base;
- int rc;
-
-@@ -272,16 +280,18 @@ static int __devinit vsc_sata_init_one (
- }
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- /*
- * Use 32 bit DMA mask, because 64 bit address support is poor.
- */
-- rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL);
-+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (rc)
- goto err_out_regions;
-- rc = pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL);
-+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
- if (rc)
- goto err_out_regions;
-
-@@ -291,7 +301,7 @@ static int __devinit vsc_sata_init_one (
- goto err_out_regions;
- }
- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-+ probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- mmio_base = ioremap(pci_resource_start(pdev, 0),
-@@ -320,6 +330,7 @@ static int __devinit vsc_sata_init_one (
- * if we don't fill these
- */
- probe_ent->pio_mask = 0x1f;
-+ probe_ent->mwdma_mask = 0x07;
- probe_ent->udma_mask = 0x7f;
-
- /* We have 4 ports per PCI function */
-@@ -330,6 +341,14 @@ static int __devinit vsc_sata_init_one (
-
- pci_set_master(pdev);
-
-+ /*
-+ * Config offset 0x98 is "Extended Control and Status Register 0"
-+ * Default value is (1 << 28). All bits except bit 28 are reserved in
-+ * DPA mode. If bit 28 is set, LED 0 reflects all ports' activity.
-+ * If bit 28 is clear, each port has its own LED.
-+ */
-+ pci_write_config_dword(pdev, 0x98, 0);
-+
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
-@@ -341,7 +360,8 @@ err_out_free_ent:
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
-@@ -382,6 +402,7 @@ MODULE_AUTHOR("Jeremy Higdon");
- MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- module_init(vsc_sata_init);
- module_exit(vsc_sata_exit);
---- /dev/null 2005-10-24 22:31:15.478015192 +0400
-+++ ./drivers/scsi/libata-dump.c 2005-10-26 14:55:16.988918072 +0400
-@@ -0,0 +1,92 @@
-+/*
-+ libata-dump.c - helper library for SATA diskdump
-+*/
-+
-+#include <linux/kernel.h>
-+#include <linux/blkdev.h>
-+#include <linux/spinlock.h>
-+#include <scsi/scsi.h>
-+#include "scsi.h"
-+#include <scsi/scsi_host.h>
-+#include <linux/libata.h>
-+#include <asm/uaccess.h>
-+
-+#include "libata.h"
-+
-+int ata_scsi_dump_sanity_check(struct scsi_device *sdev)
-+{
-+ struct ata_port *ap;
-+ struct ata_device *dev;
-+
-+ ap = (struct ata_port *) &sdev->host->hostdata[0];
-+ dev = ata_scsi_find_dev(ap, sdev);
-+
-+ if (!ata_dev_present(dev))
-+ return -EIO;
-+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
-+ return -EIO;
-+
-+ return 0;
-+}
-+
-+static int ata_scsi_dump_run_bottomhalf(struct ata_port *ap)
-+{
-+ static struct pt_regs regs; /* dummy */
-+ struct ata_host_set *host_set;
-+ struct ata_queued_cmd *qc;
-+ int handled = 0;
-+
-+ host_set = ap->host_set;
-+
-+ if (!list_empty(&ap->pio_task.entry)) {
-+ list_del_init(&ap->pio_task.entry);
-+ clear_bit(0, &ap->pio_task.pending);
-+
-+ ata_pio_task(ap);
-+ handled = 1;
-+ }
-+
-+ qc = ata_qc_from_tag(ap, ap->active_tag);
-+ if (qc) {
-+ ap->ops->irq_handler(host_set->irq, host_set, &regs);
-+ handled = 1;
-+ }
-+
-+ return handled;
-+}
-+
-+int ata_scsi_dump_quiesce(struct scsi_device *sdev)
-+{
-+ struct ata_port *ap;
-+ struct ata_device *dev;
-+ int handled;
-+
-+ ap = (struct ata_port *) &sdev->host->hostdata[0];
-+ dev = ata_scsi_find_dev(ap, sdev);
-+
-+ do {
-+ handled = ata_scsi_dump_run_bottomhalf(ap);
-+ } while (handled);
-+
-+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
-+ return -EIO;
-+
-+ return 0;
-+}
-+
-+void ata_scsi_dump_poll(struct scsi_device *sdev)
-+{
-+ struct ata_port *ap;
-+ struct ata_device *dev;
-+
-+ ap = (struct ata_port *) &sdev->host->hostdata[0];
-+ dev = ata_scsi_find_dev(ap, sdev);
-+
-+ if (ap->flags & ATA_FLAG_PORT_DISABLED) {
-+ printk(KERN_ERR "ata%u(%u): port disabled\n",
-+ ap->id, dev->devno);
-+ return;
-+ }
-+
-+ ata_scsi_dump_run_bottomhalf(ap);
-+}
---- ./drivers/scsi/sata_svw.c.libata 2005-09-26 13:33:14.000000000 +0400
-+++ ./drivers/scsi/sata_svw.c 2005-10-26 14:55:16.997916704 +0400
-@@ -49,7 +49,7 @@
- #endif /* CONFIG_PPC_OF */
-
- #define DRV_NAME "sata_svw"
--#define DRV_VERSION "1.04"
-+#define DRV_VERSION "1.06"
-
- /* Taskfile registers offsets */
- #define K2_SATA_TF_CMD_OFFSET 0x00
-@@ -148,7 +148,73 @@ static void k2_sata_tf_read(struct ata_p
- }
- }
-
-+/**
-+ * k2_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
-+ * @qc: Info associated with this ATA transaction.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
-+ u8 dmactl;
-+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
-+ /* load PRD table addr. */
-+ mb(); /* make sure PRD table writes are visible to controller */
-+ writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
-+
-+ /* specify data direction, triple-check start bit is clear */
-+ dmactl = readb(mmio + ATA_DMA_CMD);
-+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-+ if (!rw)
-+ dmactl |= ATA_DMA_WR;
-+ writeb(dmactl, mmio + ATA_DMA_CMD);
-+
-+ /* issue r/w command if this is not a ATA DMA command*/
-+ if (qc->tf.protocol != ATA_PROT_DMA)
-+ ap->ops->exec_command(ap, &qc->tf);
-+}
-
-+/**
-+ * k2_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
-+ * @qc: Info associated with this ATA transaction.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
-+ u8 dmactl;
-+
-+ /* start host DMA transaction */
-+ dmactl = readb(mmio + ATA_DMA_CMD);
-+ writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
-+ /* There is a race condition in certain SATA controllers that can
-+ be seen when the r/w command is given to the controller before the
-+ host DMA is started. On a Read command, the controller would initiate
-+ the command to the drive even before it sees the DMA start. When there
-+ are very fast drives connected to the controller, or when the data request
-+ hits in the drive cache, there is the possibility that the drive returns a part
-+ or all of the requested data to the controller before the DMA start is issued.
-+ In this case, the controller would become confused as to what to do with the data.
-+ In the worst case when all the data is returned back to the controller, the
-+ controller could hang. In other cases it could return partial data returning
-+ in data corruption. This problem has been seen in PPC systems and can also appear
-+ on an system with very fast disks, where the SATA controller is sitting behind a
-+ number of bridges, and hence there is significant latency between the r/w command
-+ and the start command. */
-+ /* issue r/w command if the access is to ATA*/
-+ if (qc->tf.protocol == ATA_PROT_DMA)
-+ ap->ops->exec_command(ap, &qc->tf);
-+}
-+
-+
- static u8 k2_stat_check_status(struct ata_port *ap)
- {
- return readl((void *) ap->ioaddr.status_addr);
-@@ -179,7 +245,7 @@ static int k2_sata_proc_info(struct Scsi
- return 0;
-
- /* Find the OF node for the PCI device proper */
-- np = pci_device_to_OF_node(ap->host_set->pdev);
-+ np = pci_device_to_OF_node(to_pci_dev(ap->host_set->dev));
- if (np == NULL)
- return 0;
-
-@@ -205,6 +271,7 @@ static int k2_sata_proc_info(struct Scsi
- static Scsi_Host_Template k2_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -229,10 +296,13 @@ static struct ata_port_operations k2_sat
- .tf_load = k2_sata_tf_load,
- .tf_read = k2_sata_tf_read,
- .check_status = k2_stat_check_status,
-- .exec_command = ata_exec_command_mmio,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = sata_phy_reset,
-- .bmdma_setup = ata_bmdma_setup_mmio,
-- .bmdma_start = ata_bmdma_start_mmio,
-+ .bmdma_setup = k2_bmdma_setup_mmio,
-+ .bmdma_start = k2_bmdma_start_mmio,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
-@@ -242,6 +312,7 @@ static struct ata_port_operations k2_sat
- .scr_write = k2_sata_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
-@@ -270,7 +341,9 @@ static int k2_sata_init_one (struct pci_
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
- void *mmio_base;
-+ int pci_dev_busy = 0;
- int rc;
-+ int i;
-
- if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
-@@ -291,8 +364,10 @@ static int k2_sata_init_one (struct pci_
-
- /* Request PCI regions */
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -308,7 +383,7 @@ static int k2_sata_init_one (struct pci_
- }
-
- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-+ probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- mmio_base = ioremap(pci_resource_start(pdev, 5),
-@@ -321,7 +396,7 @@ static int k2_sata_init_one (struct pci_
-
- /* Clear a magic bit in SCR1 according to Darwin, those help
- * some funky seagate drives (though so far, those were already
-- * set by the firmware on the machines I had access to
-+ * set by the firmware on the machines I had access to)
- */
- writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
- mmio_base + K2_SATA_SICR1_OFFSET);
-@@ -343,13 +418,14 @@ static int k2_sata_init_one (struct pci_
- * if we don't fill these
- */
- probe_ent->pio_mask = 0x1f;
-+ probe_ent->mwdma_mask = 0x7;
- probe_ent->udma_mask = 0x7f;
-
-- /* We have 4 ports per PCI function */
-- k2_sata_setup_port(&probe_ent->port[0], base + 0 * K2_SATA_PORT_OFFSET);
-- k2_sata_setup_port(&probe_ent->port[1], base + 1 * K2_SATA_PORT_OFFSET);
-- k2_sata_setup_port(&probe_ent->port[2], base + 2 * K2_SATA_PORT_OFFSET);
-- k2_sata_setup_port(&probe_ent->port[3], base + 3 * K2_SATA_PORT_OFFSET);
-+ /* 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++)
-+ k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
-
- pci_set_master(pdev);
-
-@@ -364,13 +440,22 @@ err_out_free_ent:
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
--
-+/* 0x240 is device ID for Apple K2 device
-+ * 0x241 is device ID for Serverworks Frodo4
-+ * 0x242 is device ID for Serverworks Frodo8
-+ * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA
-+ * controller
-+ * */
- static struct pci_device_id k2_sata_pci_tbl[] = {
-- { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-+ { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-+ { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-+ { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-+ { 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
- { }
- };
-
-@@ -388,6 +473,7 @@ static int __init k2_sata_init(void)
- return pci_module_init(&k2_sata_pci_driver);
- }
-
-+
- static void __exit k2_sata_exit(void)
- {
- pci_unregister_driver(&k2_sata_pci_driver);
-@@ -398,6 +484,7 @@ MODULE_AUTHOR("Benjamin Herrenschmidt");
- MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, k2_sata_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- module_init(k2_sata_init);
- module_exit(k2_sata_exit);
---- ./drivers/scsi/libata-core.c.libata 2005-09-26 13:33:11.000000000 +0400
-+++ ./drivers/scsi/libata-core.c 2005-10-26 14:55:16.987918224 +0400
-@@ -28,6 +28,7 @@
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <linux/list.h>
-+#include <linux/mm.h>
- #include <linux/highmem.h>
- #include <linux/spinlock.h>
- #include <linux/blkdev.h>
-@@ -39,22 +40,27 @@
- #include <linux/workqueue.h>
- #include <scsi/scsi.h>
- #include "scsi.h"
-+#include "scsi_priv.h"
- #include <scsi/scsi_host.h>
- #include <linux/libata.h>
- #include <asm/io.h>
- #include <asm/semaphore.h>
-+#include <asm/byteorder.h>
-
- #include "libata.h"
-
- static unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat,
- unsigned long tmout);
--static void __ata_dev_select (struct ata_port *ap, unsigned int device);
--static void ata_host_set_pio(struct ata_port *ap);
--static void ata_host_set_udma(struct ata_port *ap);
--static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
--static void ata_dev_set_udma(struct ata_port *ap, unsigned int device);
- static void ata_set_mode(struct ata_port *ap);
-+static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
-+static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
-+static int fgb(u32 bitmap);
-+static int ata_choose_xfer_mode(struct ata_port *ap,
-+ u8 *xfer_mode_out,
-+ unsigned int *xfer_shift_out);
-+static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
-+static void __ata_qc_complete(struct ata_queued_cmd *qc);
-
- static unsigned int ata_unique_id = 1;
- static struct workqueue_struct *ata_wq;
-@@ -62,19 +68,20 @@ static struct workqueue_struct *ata_wq;
- MODULE_AUTHOR("Jeff Garzik");
- MODULE_DESCRIPTION("Library module for ATA devices");
- MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-
- /**
-- * ata_tf_load_pio - send taskfile registers to host controller
-+ * ata_tf_load - send taskfile registers to host controller
- * @ap: Port to which output is sent
- * @tf: ATA taskfile register set
- *
-- * Outputs ATA taskfile to standard ATA host controller using PIO.
-+ * Outputs ATA taskfile to standard ATA host controller.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
--void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-@@ -132,23 +139,23 @@ void ata_tf_load_pio(struct ata_port *ap
- * Inherited from caller.
- */
-
--void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
- if (tf->ctl != ap->last_ctl) {
-- writeb(tf->ctl, ap->ioaddr.ctl_addr);
-+ writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
- ap->last_ctl = tf->ctl;
- ata_wait_idle(ap);
- }
-
- if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-- writeb(tf->hob_feature, (void *) ioaddr->feature_addr);
-- writeb(tf->hob_nsect, (void *) ioaddr->nsect_addr);
-- writeb(tf->hob_lbal, (void *) ioaddr->lbal_addr);
-- writeb(tf->hob_lbam, (void *) ioaddr->lbam_addr);
-- writeb(tf->hob_lbah, (void *) ioaddr->lbah_addr);
-+ writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
-+ writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
-+ writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
-+ writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
-+ writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
- VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
- tf->hob_feature,
- tf->hob_nsect,
-@@ -158,11 +165,11 @@ void ata_tf_load_mmio(struct ata_port *a
- }
-
- if (is_addr) {
-- writeb(tf->feature, (void *) ioaddr->feature_addr);
-- writeb(tf->nsect, (void *) ioaddr->nsect_addr);
-- writeb(tf->lbal, (void *) ioaddr->lbal_addr);
-- writeb(tf->lbam, (void *) ioaddr->lbam_addr);
-- writeb(tf->lbah, (void *) ioaddr->lbah_addr);
-+ writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
-+ writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
-+ writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
-+ writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
-+ writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
- VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
- tf->feature,
- tf->nsect,
-@@ -172,13 +179,43 @@ void ata_tf_load_mmio(struct ata_port *a
- }
-
- if (tf->flags & ATA_TFLAG_DEVICE) {
-- writeb(tf->device, (void *) ioaddr->device_addr);
-+ writeb(tf->device, (void __iomem *) ioaddr->device_addr);
- VPRINTK("device 0x%X\n", tf->device);
- }
-
- ata_wait_idle(ap);
- }
-
-+
-+/**
-+ * ata_tf_load - send taskfile registers to host controller
-+ * @ap: Port to which output is sent
-+ * @tf: ATA taskfile register set
-+ *
-+ * Outputs ATA taskfile to standard ATA host controller using MMIO
-+ * or PIO as indicated by the ATA_FLAG_MMIO flag.
-+ * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
-+ * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
-+ * hob_lbal, hob_lbam, and hob_lbah.
-+ *
-+ * This function waits for idle (!BUSY and !DRQ) after writing
-+ * registers. If the control register has a new value, this
-+ * function also waits for idle after writing control and before
-+ * writing the remaining registers.
-+ *
-+ * May be used as the tf_load() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ ata_tf_load_mmio(ap, tf);
-+ else
-+ ata_tf_load_pio(ap, tf);
-+}
-+
- /**
- * ata_exec_command_pio - issue ATA command to host controller
- * @ap: port to which command is being issued
-@@ -191,7 +228,7 @@ void ata_tf_load_mmio(struct ata_port *a
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
-@@ -212,20 +249,40 @@ void ata_exec_command_pio(struct ata_por
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
-- writeb(tf->command, (void *) ap->ioaddr.command_addr);
-+ writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
- ata_pause(ap);
- }
-
-+
-+/**
-+ * ata_exec_command - issue ATA command to host controller
-+ * @ap: port to which command is being issued
-+ * @tf: ATA taskfile register set
-+ *
-+ * Issues PIO/MMIO write to ATA command register, with proper
-+ * synchronization with interrupt handler / other threads.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ ata_exec_command_mmio(ap, tf);
-+ else
-+ ata_exec_command_pio(ap, tf);
-+}
-+
- /**
- * ata_exec - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
-- * Issues PIO write to ATA command register, with proper
-+ * Issues PIO/MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
-@@ -248,7 +305,7 @@ static inline void ata_exec(struct ata_p
- * @tf: ATA taskfile register set
- *
- * Issues ATA taskfile register set to ATA host controller,
-- * via PIO, with proper synchronization with interrupt handler and
-+ * with proper synchronization with interrupt handler and
- * other threads.
- *
- * LOCKING:
-@@ -268,7 +325,7 @@ static void ata_tf_to_host(struct ata_po
- * @tf: ATA taskfile register set
- *
- * Issues ATA taskfile register set to ATA host controller,
-- * via PIO, with proper synchronization with interrupt handler and
-+ * with proper synchronization with interrupt handler and
- * other threads.
- *
- * LOCKING:
-@@ -287,13 +344,13 @@ void ata_tf_to_host_nolock(struct ata_po
- * @tf: ATA taskfile register set for storing input
- *
- * Reads ATA taskfile registers for currently-selected device
-- * into @tf via PIO.
-+ * into @tf.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
--void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
-@@ -325,38 +382,63 @@ void ata_tf_read_pio(struct ata_port *ap
- * Inherited from caller.
- */
-
--void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
-+static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
-- tf->nsect = readb((void *)ioaddr->nsect_addr);
-- tf->lbal = readb((void *)ioaddr->lbal_addr);
-- tf->lbam = readb((void *)ioaddr->lbam_addr);
-- tf->lbah = readb((void *)ioaddr->lbah_addr);
-- tf->device = readb((void *)ioaddr->device_addr);
-+ tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
-+ tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
-+ tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
-+ tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
-+ tf->device = readb((void __iomem *)ioaddr->device_addr);
-
- if (tf->flags & ATA_TFLAG_LBA48) {
-- writeb(tf->ctl | ATA_HOB, ap->ioaddr.ctl_addr);
-- tf->hob_feature = readb((void *)ioaddr->error_addr);
-- tf->hob_nsect = readb((void *)ioaddr->nsect_addr);
-- tf->hob_lbal = readb((void *)ioaddr->lbal_addr);
-- tf->hob_lbam = readb((void *)ioaddr->lbam_addr);
-- tf->hob_lbah = readb((void *)ioaddr->lbah_addr);
-+ writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
-+ tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
-+ tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
-+ tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
-+ tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
-+ tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
- }
- }
-
-+
-+/**
-+ * ata_tf_read - input device's ATA taskfile shadow registers
-+ * @ap: Port from which input is read
-+ * @tf: ATA taskfile register set for storing input
-+ *
-+ * Reads ATA taskfile registers for currently-selected device
-+ * into @tf.
-+ *
-+ * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
-+ * is set, also reads the hob registers.
-+ *
-+ * May be used as the tf_read() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ ata_tf_read_mmio(ap, tf);
-+ else
-+ ata_tf_read_pio(ap, tf);
-+}
-+
- /**
- * ata_check_status_pio - Read device status reg & clear interrupt
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
-- * via PIO and return it's value. This also clears pending interrupts
-+ * and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
--u8 ata_check_status_pio(struct ata_port *ap)
-+static u8 ata_check_status_pio(struct ata_port *ap)
- {
- return inb(ap->ioaddr.status_addr);
- }
-@@ -366,15 +448,85 @@ u8 ata_check_status_pio(struct ata_port
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
-- * via MMIO and return it's value. This also clears pending interrupts
-+ * via MMIO and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
--u8 ata_check_status_mmio(struct ata_port *ap)
-+static u8 ata_check_status_mmio(struct ata_port *ap)
-+{
-+ return readb((void __iomem *) ap->ioaddr.status_addr);
-+}
-+
-+
-+/**
-+ * ata_check_status - Read device status reg & clear interrupt
-+ * @ap: port where the device is
-+ *
-+ * Reads ATA taskfile status register for currently-selected device
-+ * and return its value. This also clears pending interrupts
-+ * from this device
-+ *
-+ * May be used as the check_status() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+u8 ata_check_status(struct ata_port *ap)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ return ata_check_status_mmio(ap);
-+ return ata_check_status_pio(ap);
-+}
-+
-+
-+/**
-+ * ata_altstatus - Read device alternate status reg
-+ * @ap: port where the device is
-+ *
-+ * Reads ATA taskfile alternate status register for
-+ * currently-selected device and return its value.
-+ *
-+ * Note: may NOT be used as the check_altstatus() entry in
-+ * ata_port_operations.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+u8 ata_altstatus(struct ata_port *ap)
-+{
-+ if (ap->ops->check_altstatus)
-+ return ap->ops->check_altstatus(ap);
-+
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ return readb((void __iomem *)ap->ioaddr.altstatus_addr);
-+ return inb(ap->ioaddr.altstatus_addr);
-+}
-+
-+
-+/**
-+ * ata_chk_err - Read device error reg
-+ * @ap: port where the device is
-+ *
-+ * Reads ATA taskfile error register for
-+ * currently-selected device and return its value.
-+ *
-+ * Note: may NOT be used as the check_err() entry in
-+ * ata_port_operations.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+u8 ata_chk_err(struct ata_port *ap)
- {
-- return readb((void *) ap->ioaddr.status_addr);
-+ if (ap->ops->check_err)
-+ return ap->ops->check_err(ap);
-+
-+ if (ap->flags & ATA_FLAG_MMIO) {
-+ return readb((void __iomem *) ap->ioaddr.error_addr);
-+ }
-+ return inb(ap->ioaddr.error_addr);
- }
-
- /**
-@@ -524,7 +676,7 @@ static void ata_dev_set_protocol(struct
- dev->write_cmd = (cmd >> 8) & 0xff;
- }
-
--static const char * udma_str[] = {
-+static const char * xfer_mode_str[] = {
- "UDMA/16",
- "UDMA/25",
- "UDMA/33",
-@@ -533,11 +685,19 @@ static const char * udma_str[] = {
- "UDMA/100",
- "UDMA/133",
- "UDMA7",
-+ "MWDMA0",
-+ "MWDMA1",
-+ "MWDMA2",
-+ "PIO0",
-+ "PIO1",
-+ "PIO2",
-+ "PIO3",
-+ "PIO4",
- };
-
- /**
- * ata_udma_string - convert UDMA bit offset to string
-- * @udma_mask: mask of bits supported; only highest bit counts.
-+ * @mask: mask of bits supported; only highest bit counts.
- *
- * Determine string which represents the highest speed
- * (highest bit in @udma_mask).
-@@ -550,16 +710,24 @@ static const char * udma_str[] = {
- * @udma_mask, or the constant C string "<n/a>".
- */
-
--static const char *ata_udma_string(unsigned int udma_mask)
-+static const char *ata_mode_string(unsigned int mask)
- {
- int i;
-
-- for (i = 7; i >= 0; i--) {
-- if (udma_mask & (1 << i))
-- return udma_str[i];
-- }
-+ for (i = 7; i >= 0; i--)
-+ if (mask & (1 << i))
-+ goto out;
-+ for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--)
-+ if (mask & (1 << i))
-+ goto out;
-+ for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--)
-+ if (mask & (1 << i))
-+ goto out;
-
- return "<n/a>";
-+
-+out:
-+ return xfer_mode_str[i];
- }
-
- /**
-@@ -586,7 +754,7 @@ static unsigned int ata_pio_devchk(struc
- struct ata_ioports *ioaddr = &ap->ioaddr;
- u8 nsect, lbal;
-
-- __ata_dev_select(ap, device);
-+ ap->ops->dev_select(ap, device);
-
- outb(0x55, ioaddr->nsect_addr);
- outb(0xaa, ioaddr->lbal_addr);
-@@ -630,19 +798,19 @@ static unsigned int ata_mmio_devchk(stru
- struct ata_ioports *ioaddr = &ap->ioaddr;
- u8 nsect, lbal;
-
-- __ata_dev_select(ap, device);
-+ ap->ops->dev_select(ap, device);
-
-- writeb(0x55, (void *) ioaddr->nsect_addr);
-- writeb(0xaa, (void *) ioaddr->lbal_addr);
-+ writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-+ writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
-
-- writeb(0xaa, (void *) ioaddr->nsect_addr);
-- writeb(0x55, (void *) ioaddr->lbal_addr);
-+ writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
-+ writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
-
-- writeb(0x55, (void *) ioaddr->nsect_addr);
-- writeb(0xaa, (void *) ioaddr->lbal_addr);
-+ writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-+ writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
-
-- nsect = readb((void *) ioaddr->nsect_addr);
-- lbal = readb((void *) ioaddr->lbal_addr);
-+ nsect = readb((void __iomem *) ioaddr->nsect_addr);
-+ lbal = readb((void __iomem *) ioaddr->lbal_addr);
-
- if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
-@@ -651,7 +819,7 @@ static unsigned int ata_mmio_devchk(stru
- }
-
- /**
-- * ata_dev_devchk - PATA device presence detection
-+ * ata_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
-@@ -663,7 +831,7 @@ static unsigned int ata_mmio_devchk(stru
- * caller.
- */
-
--static unsigned int ata_dev_devchk(struct ata_port *ap,
-+static unsigned int ata_devchk(struct ata_port *ap,
- unsigned int device)
- {
- if (ap->flags & ATA_FLAG_MMIO)
-@@ -687,7 +855,7 @@ static unsigned int ata_dev_devchk(struc
- * the event of failure.
- */
-
--static unsigned int ata_dev_classify(struct ata_taskfile *tf)
-+unsigned int ata_dev_classify(struct ata_taskfile *tf)
- {
- /* Apple's open source Darwin code hints that some devices only
- * put a proper signature into the LBA mid/high registers,
-@@ -735,7 +903,7 @@ static u8 ata_dev_try_classify(struct at
- unsigned int class;
- u8 err;
-
-- __ata_dev_select(ap, device);
-+ ap->ops->dev_select(ap, device);
-
- memset(&tf, 0, sizeof(tf));
-
-@@ -766,7 +934,7 @@ static u8 ata_dev_try_classify(struct at
-
- /**
- * ata_dev_id_string - Convert IDENTIFY DEVICE page into string
-- * @dev: Device whose IDENTIFY DEVICE results we will examine
-+ * @id: IDENTIFY DEVICE results we will examine
- * @s: string into which data is output
- * @ofs: offset into identify device page
- * @len: length of string to return. must be an even number.
-@@ -779,17 +947,17 @@ static u8 ata_dev_try_classify(struct at
- * caller.
- */
-
--void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
-+void ata_dev_id_string(u16 *id, unsigned char *s,
- unsigned int ofs, unsigned int len)
- {
- unsigned int c;
-
- while (len > 0) {
-- c = dev->id[ofs] >> 8;
-+ c = id[ofs] >> 8;
- *s = c;
- s++;
-
-- c = dev->id[ofs] & 0xff;
-+ c = id[ofs] & 0xff;
- *s = c;
- s++;
-
-@@ -798,20 +966,40 @@ void ata_dev_id_string(struct ata_device
- }
- }
-
-+
-+/**
-+ * ata_noop_dev_select - Select device 0/1 on ATA bus
-+ * @ap: ATA channel to manipulate
-+ * @device: ATA device (numbered from zero) to select
-+ *
-+ * This function performs no actual function.
-+ *
-+ * May be used as the dev_select() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * caller.
-+ */
-+void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
-+{
-+}
-+
-+
- /**
-- * __ata_dev_select - Select device 0/1 on ATA bus
-+ * ata_std_dev_select - Select device 0/1 on ATA bus
- * @ap: ATA channel to manipulate
- * @device: ATA device (numbered from zero) to select
- *
- * Use the method defined in the ATA specification to
- * make either device 0, or device 1, active on the
-- * ATA channel.
-+ * ATA channel. Works with both PIO and MMIO.
-+ *
-+ * May be used as the dev_select() entry in ata_port_operations.
- *
- * LOCKING:
- * caller.
- */
-
--static void __ata_dev_select (struct ata_port *ap, unsigned int device)
-+void ata_std_dev_select (struct ata_port *ap, unsigned int device)
- {
- u8 tmp;
-
-@@ -821,7 +1009,7 @@ static void __ata_dev_select (struct ata
- tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
- if (ap->flags & ATA_FLAG_MMIO) {
-- writeb(tmp, (void *) ap->ioaddr.device_addr);
-+ writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
- } else {
- outb(tmp, ap->ioaddr.device_addr);
- }
-@@ -839,7 +1027,7 @@ static void __ata_dev_select (struct ata
- * make either device 0, or device 1, active on the
- * ATA channel.
- *
-- * This is a high-level version of __ata_dev_select(),
-+ * This is a high-level version of ata_std_dev_select(),
- * which additionally provides the services of inserting
- * the proper pauses and status polling, where needed.
- *
-@@ -856,7 +1044,7 @@ void ata_dev_select(struct ata_port *ap,
- if (wait)
- ata_wait_idle(ap);
-
-- __ata_dev_select(ap, device);
-+ ap->ops->dev_select(ap, device);
-
- if (wait) {
- if (can_sleep && ap->device[device].class == ATA_DEV_ATAPI)
-@@ -930,10 +1118,14 @@ static void ata_dev_identify(struct ata_
- {
- struct ata_device *dev = &ap->device[device];
- unsigned int i;
-- u16 tmp, udma_modes;
-+ u16 tmp;
-+ unsigned long xfer_modes;
- u8 status;
-- struct ata_taskfile tf;
- unsigned int using_edd;
-+ DECLARE_COMPLETION(wait);
-+ struct ata_queued_cmd *qc;
-+ unsigned long flags;
-+ int rc;
-
- if (!ata_dev_present(dev)) {
- DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
-@@ -953,27 +1145,34 @@ static void ata_dev_identify(struct ata_
-
- ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
-
--retry:
-- ata_tf_init(ap, &tf, device);
-- tf.ctl |= ATA_NIEN;
-- tf.protocol = ATA_PROT_PIO;
-+ qc = ata_qc_new_init(ap, dev);
-+ BUG_ON(qc == NULL);
-+
-+ ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-+ qc->dma_dir = DMA_FROM_DEVICE;
-+ qc->tf.protocol = ATA_PROT_PIO;
-+ qc->nsect = 1;
-
-+retry:
- if (dev->class == ATA_DEV_ATA) {
-- tf.command = ATA_CMD_ID_ATA;
-+ qc->tf.command = ATA_CMD_ID_ATA;
- DPRINTK("do ATA identify\n");
- } else {
-- tf.command = ATA_CMD_ID_ATAPI;
-+ qc->tf.command = ATA_CMD_ID_ATAPI;
- DPRINTK("do ATAPI identify\n");
- }
-
-- ata_tf_to_host(ap, &tf);
-+ qc->waiting = &wait;
-+ qc->complete_fn = ata_qc_complete_noop;
-
-- /* crazy ATAPI devices... */
-- if (dev->class == ATA_DEV_ATAPI)
-- msleep(150);
-+ spin_lock_irqsave(&ap->host_set->lock, flags);
-+ rc = ata_qc_issue(qc);
-+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-- if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT))
-+ if (rc)
- goto err_out;
-+ else
-+ wait_for_completion(&wait);
-
- status = ata_chk_status(ap);
- if (status & ATA_ERR) {
-@@ -988,44 +1187,21 @@ retry:
- * ATA software reset (SRST, the default) does not appear
- * to have this problem.
- */
-- if ((using_edd) && (tf.command == ATA_CMD_ID_ATA)) {
-+ if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
- u8 err = ata_chk_err(ap);
- if (err & ATA_ABORTED) {
- dev->class = ATA_DEV_ATAPI;
-+ qc->cursg = 0;
-+ qc->cursg_ofs = 0;
-+ qc->cursect = 0;
-+ qc->nsect = 1;
- goto retry;
- }
- }
- goto err_out;
- }
-
-- /* make sure we have BSY=0, DRQ=1 */
-- if ((status & ATA_DRQ) == 0) {
-- printk(KERN_WARNING "ata%u: dev %u (ATA%s?) not returning id page (0x%x)\n",
-- ap->id, device,
-- dev->class == ATA_DEV_ATA ? "" : "PI",
-- status);
-- goto err_out;
-- }
--
-- /* read IDENTIFY [X] DEVICE page */
-- if (ap->flags & ATA_FLAG_MMIO) {
-- for (i = 0; i < ATA_ID_WORDS; i++)
-- dev->id[i] = readw((void *)ap->ioaddr.data_addr);
-- } else
-- for (i = 0; i < ATA_ID_WORDS; i++)
-- dev->id[i] = inw(ap->ioaddr.data_addr);
--
-- /* wait for host_idle */
-- status = ata_wait_idle(ap);
-- if (status & (ATA_BUSY | ATA_DRQ)) {
-- printk(KERN_WARNING "ata%u: dev %u (ATA%s?) error after id page (0x%x)\n",
-- ap->id, device,
-- dev->class == ATA_DEV_ATA ? "" : "PI",
-- status);
-- goto err_out;
-- }
--
-- ata_irq_on(ap); /* re-enable interrupts */
-+ swap_buf_le16(dev->id, ATA_ID_WORDS);
-
- /* print device capabilities */
- printk(KERN_DEBUG "ata%u: dev %u cfg "
-@@ -1040,24 +1216,25 @@ retry:
- */
-
- /* we require LBA and DMA support (bits 8 & 9 of word 49) */
-- if (!ata_id_has_dma(dev) || !ata_id_has_lba(dev)) {
-+ if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
- printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
- goto err_out_nosup;
- }
-
-- /* we require UDMA support */
-- udma_modes =
-- tmp = dev->id[ATA_ID_UDMA_MODES];
-- if ((tmp & 0xff) == 0) {
-- printk(KERN_DEBUG "ata%u: no udma\n", ap->id);
-- goto err_out_nosup;
-+ /* quick-n-dirty find max transfer mode; for printk only */
-+ xfer_modes = dev->id[ATA_ID_UDMA_MODES];
-+ if (!xfer_modes)
-+ xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
-+ if (!xfer_modes) {
-+ xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
-+ xfer_modes |= (0x7 << ATA_SHIFT_PIO);
- }
-
- ata_dump_id(dev);
-
- /* ATA-specific feature tests */
- if (dev->class == ATA_DEV_ATA) {
-- if (!ata_id_is_ata(dev)) /* sanity check */
-+ if (!ata_id_is_ata(dev->id)) /* sanity check */
- goto err_out_nosup;
-
- tmp = dev->id[ATA_ID_MAJOR_VER];
-@@ -1071,11 +1248,11 @@ retry:
- goto err_out_nosup;
- }
-
-- if (ata_id_has_lba48(dev)) {
-+ if (ata_id_has_lba48(dev->id)) {
- dev->flags |= ATA_DFLAG_LBA48;
-- dev->n_sectors = ata_id_u64(dev, 100);
-+ dev->n_sectors = ata_id_u64(dev->id, 100);
- } else {
-- dev->n_sectors = ata_id_u32(dev, 60);
-+ dev->n_sectors = ata_id_u32(dev->id, 60);
- }
-
- ap->host->max_cmd_len = 16;
-@@ -1083,25 +1260,28 @@ retry:
- /* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
- ap->id, device,
-- ata_udma_string(udma_modes),
-+ ata_mode_string(xfer_modes),
- (unsigned long long)dev->n_sectors,
- dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
- }
-
- /* ATAPI-specific feature tests */
- else {
-- if (ata_id_is_ata(dev)) /* sanity check */
-+ if (ata_id_is_ata(dev->id)) /* sanity check */
- goto err_out_nosup;
-
-- /* see if 16-byte commands supported */
-- tmp = dev->id[0] & 0x3;
-- if (tmp == 1)
-- ap->host->max_cmd_len = 16;
-+ rc = atapi_cdb_len(dev->id);
-+ if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
-+ printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
-+ goto err_out_nosup;
-+ }
-+ ap->cdb_len = (unsigned int) rc;
-+ ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
-
- /* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
- ap->id, device,
-- ata_udma_string(udma_modes));
-+ ata_mode_string(xfer_modes));
- }
-
- DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
-@@ -1111,16 +1291,51 @@ err_out_nosup:
- printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
- ap->id, device);
- err_out:
-- ata_irq_on(ap); /* re-enable interrupts */
- dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */
- DPRINTK("EXIT, err\n");
- }
-
-+
-+static inline u8 ata_dev_knobble(struct ata_port *ap)
-+{
-+ return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
-+}
-+
-+/**
-+ * ata_dev_config - Run device specific handlers and check for
-+ * SATA->PATA bridges
-+ * @ap: Bus
-+ * @i: Device
-+ *
-+ * LOCKING:
-+ */
-+
-+void ata_dev_config(struct ata_port *ap, unsigned int i)
-+{
-+ /* limit bridge transfers to udma5, 200 sectors */
-+ if (ata_dev_knobble(ap)) {
-+ printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
-+ ap->id, ap->device->devno);
-+ ap->udma_mask &= ATA_UDMA5;
-+ ap->host->max_sectors = ATA_MAX_SECTORS;
-+ ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
-+ ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
-+ }
-+
-+ if (ap->ops->dev_config)
-+ ap->ops->dev_config(ap, &ap->device[i]);
-+}
-+
- /**
- * ata_bus_probe - Reset and probe ATA bus
- * @ap: Bus to probe
- *
-+ * Master ATA bus probing function. Initiates a hardware-dependent
-+ * bus reset, then attempts to identify any devices found on
-+ * the bus.
-+ *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- * RETURNS:
- * Zero on success, non-zero on error.
-@@ -1138,8 +1353,7 @@ static int ata_bus_probe(struct ata_port
- ata_dev_identify(ap, i);
- if (ata_dev_present(&ap->device[i])) {
- found = 1;
-- if (ap->ops->dev_config)
-- ap->ops->dev_config(ap, &ap->device[i]);
-+ ata_dev_config(ap,i);
- }
- }
-
-@@ -1159,10 +1373,14 @@ err_out:
- }
-
- /**
-- * ata_port_probe -
-- * @ap:
-+ * ata_port_probe - Mark port as enabled
-+ * @ap: Port for which we indicate enablement
- *
-- * LOCKING:
-+ * Modify @ap data structure such that the system
-+ * thinks that the entire port is enabled.
-+ *
-+ * LOCKING: host_set lock, or some other form of
-+ * serialization.
- */
-
- void ata_port_probe(struct ata_port *ap)
-@@ -1171,23 +1389,30 @@ void ata_port_probe(struct ata_port *ap)
- }
-
- /**
-- * sata_phy_reset -
-- * @ap:
-+ * __sata_phy_reset - Wake/reset a low-level SATA PHY
-+ * @ap: SATA port associated with target SATA PHY.
-+ *
-+ * This function issues commands to standard SATA Sxxx
-+ * PHY registers, to wake up the phy (and device), and
-+ * clear any reset condition.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- */
--void sata_phy_reset(struct ata_port *ap)
-+void __sata_phy_reset(struct ata_port *ap)
- {
- u32 sstatus;
- unsigned long timeout = jiffies + (HZ * 5);
-
- if (ap->flags & ATA_FLAG_SATA_RESET) {
-- scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
-- scr_read(ap, SCR_STATUS); /* dummy read; flush */
-- udelay(400); /* FIXME: a guess */
-+ /* issue phy wake/reset */
-+ scr_write_flush(ap, SCR_CONTROL, 0x301);
-+ /* Couldn't find anything in SATA I/II specs, but
-+ * AHCI-1.1 10.4.2 says at least 1 ms. */
-+ mdelay(1);
- }
-- scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */
-+ scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
-
- /* wait for phy to become ready, if necessary */
- do {
-@@ -1215,14 +1440,39 @@ void sata_phy_reset(struct ata_port *ap)
- return;
- }
-
-- ata_bus_reset(ap);
-+ ap->cbl = ATA_CBL_SATA;
- }
-
- /**
-- * ata_port_disable -
-- * @ap:
-+ * sata_phy_reset - Reset SATA bus.
-+ * @ap: SATA port associated with target SATA PHY.
-+ *
-+ * This function resets the SATA bus, and then probes
-+ * the bus for devices.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
-+ *
-+ */
-+void sata_phy_reset(struct ata_port *ap)
-+{
-+ __sata_phy_reset(ap);
-+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
-+ return;
-+ ata_bus_reset(ap);
-+}
-+
-+/**
-+ * ata_port_disable - Disable port.
-+ * @ap: Port to be disabled.
-+ *
-+ * Modify @ap data structure such that the system
-+ * thinks that the entire port is disabled, and should
-+ * never attempt to probe or communicate with devices
-+ * on this port.
-+ *
-+ * LOCKING: host_set lock, or some other form of
-+ * serialization.
- */
-
- void ata_port_disable(struct ata_port *ap)
-@@ -1232,38 +1482,135 @@ void ata_port_disable(struct ata_port *a
- ap->flags |= ATA_FLAG_PORT_DISABLED;
- }
-
-+static struct {
-+ unsigned int shift;
-+ u8 base;
-+} xfer_mode_classes[] = {
-+ { ATA_SHIFT_UDMA, XFER_UDMA_0 },
-+ { ATA_SHIFT_MWDMA, XFER_MW_DMA_0 },
-+ { ATA_SHIFT_PIO, XFER_PIO_0 },
-+};
-+
-+static inline u8 base_from_shift(unsigned int shift)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++)
-+ if (xfer_mode_classes[i].shift == shift)
-+ return xfer_mode_classes[i].base;
-+
-+ return 0xff;
-+}
-+
-+static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
-+{
-+ int ofs, idx;
-+ u8 base;
-+
-+ if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
-+ return;
-+
-+ if (dev->xfer_shift == ATA_SHIFT_PIO)
-+ dev->flags |= ATA_DFLAG_PIO;
-+
-+ ata_dev_set_xfermode(ap, dev);
-+
-+ base = base_from_shift(dev->xfer_shift);
-+ ofs = dev->xfer_mode - base;
-+ idx = ofs + dev->xfer_shift;
-+ WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str));
-+
-+ DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n",
-+ idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs);
-+
-+ printk(KERN_INFO "ata%u: dev %u configured for %s\n",
-+ ap->id, dev->devno, xfer_mode_str[idx]);
-+}
-+
-+static int ata_host_set_pio(struct ata_port *ap)
-+{
-+ unsigned int mask;
-+ int x, i;
-+ u8 base, xfer_mode;
-+
-+ mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
-+ x = fgb(mask);
-+ if (x < 0) {
-+ printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
-+ return -1;
-+ }
-+
-+ base = base_from_shift(ATA_SHIFT_PIO);
-+ xfer_mode = base + x;
-+
-+ DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n",
-+ (int)base, (int)xfer_mode, mask, x);
-+
-+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
-+ struct ata_device *dev = &ap->device[i];
-+ if (ata_dev_present(dev)) {
-+ dev->pio_mode = xfer_mode;
-+ dev->xfer_mode = xfer_mode;
-+ dev->xfer_shift = ATA_SHIFT_PIO;
-+ if (ap->ops->set_piomode)
-+ ap->ops->set_piomode(ap, dev);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
-+ unsigned int xfer_shift)
-+{
-+ int i;
-+
-+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
-+ struct ata_device *dev = &ap->device[i];
-+ if (ata_dev_present(dev)) {
-+ dev->dma_mode = xfer_mode;
-+ dev->xfer_mode = xfer_mode;
-+ dev->xfer_shift = xfer_shift;
-+ if (ap->ops->set_dmamode)
-+ ap->ops->set_dmamode(ap, dev);
-+ }
-+ }
-+}
-+
- /**
- * ata_set_mode - Program timings and issue SET FEATURES - XFER
- * @ap: port on which timings will be programmed
- *
-+ * Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
-+ *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- */
- static void ata_set_mode(struct ata_port *ap)
- {
-- unsigned int force_pio, i;
--
-- ata_host_set_pio(ap);
-- if (ap->flags & ATA_FLAG_PORT_DISABLED)
-- return;
-+ unsigned int i, xfer_shift;
-+ u8 xfer_mode;
-+ int rc;
-
-- ata_host_set_udma(ap);
-- if (ap->flags & ATA_FLAG_PORT_DISABLED)
-- return;
-+ /* step 1: always set host PIO timings */
-+ rc = ata_host_set_pio(ap);
-+ if (rc)
-+ goto err_out;
-
--#ifdef ATA_FORCE_PIO
-- force_pio = 1;
--#else
-- force_pio = 0;
--#endif
-+ /* step 2: choose the best data xfer mode */
-+ xfer_mode = xfer_shift = 0;
-+ rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift);
-+ if (rc)
-+ goto err_out;
-
-- if (force_pio) {
-- ata_dev_set_pio(ap, 0);
-- ata_dev_set_pio(ap, 1);
-- } else {
-- ata_dev_set_udma(ap, 0);
-- ata_dev_set_udma(ap, 1);
-- }
-+ /* step 3: if that xfer mode isn't PIO, set host DMA timings */
-+ if (xfer_shift != ATA_SHIFT_PIO)
-+ ata_host_set_dma(ap, xfer_mode, xfer_shift);
-+
-+ /* step 4: update devices' xfer mode */
-+ ata_dev_set_mode(ap, &ap->device[0]);
-+ ata_dev_set_mode(ap, &ap->device[1]);
-
- if (ap->flags & ATA_FLAG_PORT_DISABLED)
- return;
-@@ -1275,6 +1622,11 @@ static void ata_set_mode(struct ata_port
- struct ata_device *dev = &ap->device[i];
- ata_dev_set_protocol(dev);
- }
-+
-+ return;
-+
-+err_out:
-+ ata_port_disable(ap);
- }
-
- /**
-@@ -1283,7 +1635,10 @@ static void ata_set_mode(struct ata_port
- * @tmout_pat: impatience timeout
- * @tmout: overall timeout
- *
-- * LOCKING:
-+ * Sleep until ATA Status register bit BSY clears,
-+ * or a timeout occurs.
-+ *
-+ * LOCKING: None.
- *
- */
-
-@@ -1328,23 +1683,23 @@ static void ata_bus_post_reset(struct at
- unsigned int dev1 = devmask & (1 << 1);
- unsigned long timeout;
-
-- /* if device 0 was found in ata_dev_devchk, wait for its
-+ /* if device 0 was found in ata_devchk, wait for its
- * BSY bit to clear
- */
- if (dev0)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-
-- /* if device 1 was found in ata_dev_devchk, wait for
-+ /* if device 1 was found in ata_devchk, wait for
- * register access, then wait for BSY to clear
- */
- timeout = jiffies + ATA_TMOUT_BOOT;
- while (dev1) {
- u8 nsect, lbal;
-
-- __ata_dev_select(ap, 1);
-+ ap->ops->dev_select(ap, 1);
- if (ap->flags & ATA_FLAG_MMIO) {
-- nsect = readb((void *) ioaddr->nsect_addr);
-- lbal = readb((void *) ioaddr->lbal_addr);
-+ nsect = readb((void __iomem *) ioaddr->nsect_addr);
-+ lbal = readb((void __iomem *) ioaddr->lbal_addr);
- } else {
- nsect = inb(ioaddr->nsect_addr);
- lbal = inb(ioaddr->lbal_addr);
-@@ -1361,18 +1716,22 @@ static void ata_bus_post_reset(struct at
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-
- /* is all this really necessary? */
-- __ata_dev_select(ap, 0);
-+ ap->ops->dev_select(ap, 0);
- if (dev1)
-- __ata_dev_select(ap, 1);
-+ ap->ops->dev_select(ap, 1);
- if (dev0)
-- __ata_dev_select(ap, 0);
-+ ap->ops->dev_select(ap, 0);
- }
-
- /**
-- * ata_bus_edd -
-- * @ap:
-+ * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
-+ * @ap: Port to reset and probe
-+ *
-+ * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
-+ * probe the bus. Not often used these days.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- */
-
-@@ -1408,11 +1767,11 @@ static unsigned int ata_bus_softreset(st
-
- /* software reset. causes dev0 to be selected */
- if (ap->flags & ATA_FLAG_MMIO) {
-- writeb(ap->ctl, ioaddr->ctl_addr);
-+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
-- writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-+ writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
-- writeb(ap->ctl, ioaddr->ctl_addr);
-+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- } else {
- outb(ap->ctl, ioaddr->ctl_addr);
- udelay(10);
-@@ -1449,8 +1808,8 @@ static unsigned int ata_bus_softreset(st
- * the device is ATA or ATAPI.
- *
- * LOCKING:
-- * Inherited from caller. Some functions called by this function
-- * obtain the host_set lock.
-+ * PCI/etc. bus probe sem.
-+ * Obtains host_set lock.
- *
- * SIDE EFFECTS:
- * Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
-@@ -1469,9 +1828,9 @@ void ata_bus_reset(struct ata_port *ap)
- if (ap->flags & ATA_FLAG_SATA_RESET)
- dev0 = 1;
- else {
-- dev0 = ata_dev_devchk(ap, 0);
-+ dev0 = ata_devchk(ap, 0);
- if (slave_possible)
-- dev1 = ata_dev_devchk(ap, 1);
-+ dev1 = ata_devchk(ap, 1);
- }
-
- if (dev0)
-@@ -1480,7 +1839,7 @@ void ata_bus_reset(struct ata_port *ap)
- devmask |= (1 << 1);
-
- /* select device 0 again */
-- __ata_dev_select(ap, 0);
-+ ap->ops->dev_select(ap, 0);
-
- /* issue bus reset */
- if (ap->flags & ATA_FLAG_SRST)
-@@ -1488,7 +1847,7 @@ void ata_bus_reset(struct ata_port *ap)
- else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) {
- /* set up device control */
- if (ap->flags & ATA_FLAG_MMIO)
-- writeb(ap->ctl, ioaddr->ctl_addr);
-+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
- rc = ata_bus_edd(ap);
-@@ -1505,13 +1864,14 @@ void ata_bus_reset(struct ata_port *ap)
- ata_dev_try_classify(ap, 1);
-
- /* re-enable interrupts */
-- ata_irq_on(ap);
-+ if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
-+ ata_irq_on(ap);
-
- /* is double-select really necessary? */
- if (ap->device[1].class != ATA_DEV_NONE)
-- __ata_dev_select(ap, 1);
-+ ap->ops->dev_select(ap, 1);
- if (ap->device[0].class != ATA_DEV_NONE)
-- __ata_dev_select(ap, 0);
-+ ap->ops->dev_select(ap, 0);
-
- /* if no devices were detected, disable this port */
- if ((ap->device[0].class == ATA_DEV_NONE) &&
-@@ -1521,7 +1881,7 @@ void ata_bus_reset(struct ata_port *ap)
- if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
- /* set up device control for ATA_FLAG_SATA_RESET */
- if (ap->flags & ATA_FLAG_MMIO)
-- writeb(ap->ctl, ioaddr->ctl_addr);
-+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
- }
-@@ -1536,222 +1896,254 @@ err_out:
- DPRINTK("EXIT\n");
- }
-
--/**
-- * ata_host_set_pio -
-- * @ap:
-- *
-- * LOCKING:
-- */
--
--static void ata_host_set_pio(struct ata_port *ap)
-+static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
- {
-- struct ata_device *master, *slave;
-- unsigned int pio, i;
-- u16 mask;
-+ printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
-+ ap->id, dev->devno);
-+}
-
-- master = &ap->device[0];
-- slave = &ap->device[1];
-+static const char * ata_dma_blacklist [] = {
-+ "WDC AC11000H",
-+ "WDC AC22100H",
-+ "WDC AC32500H",
-+ "WDC AC33100H",
-+ "WDC AC31600H",
-+ "WDC AC32100H",
-+ "WDC AC23200L",
-+ "Compaq CRD-8241B",
-+ "CRD-8400B",
-+ "CRD-8480B",
-+ "CRD-8482B",
-+ "CRD-84",
-+ "SanDisk SDP3B",
-+ "SanDisk SDP3B-64",
-+ "SANYO CD-ROM CRD",
-+ "HITACHI CDR-8",
-+ "HITACHI CDR-8335",
-+ "HITACHI CDR-8435",
-+ "Toshiba CD-ROM XM-6202B",
-+ "TOSHIBA CD-ROM XM-1702BC",
-+ "CD-532E-A",
-+ "E-IDE CD-ROM CR-840",
-+ "CD-ROM Drive/F5A",
-+ "WPI CDD-820",
-+ "SAMSUNG CD-ROM SC-148C",
-+ "SAMSUNG CD-ROM SC",
-+ "SanDisk SDP3B-64",
-+ "ATAPI CD-ROM DRIVE 40X MAXIMUM",
-+ "_NEC DV5800A",
-+};
-
-- assert (ata_dev_present(master) || ata_dev_present(slave));
-+static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
-+{
-+ unsigned char model_num[40];
-+ char *s;
-+ unsigned int len;
-+ int i;
-
-- mask = ap->pio_mask;
-- if (ata_dev_present(master))
-- mask &= (master->id[ATA_ID_PIO_MODES] & 0x03);
-- if (ata_dev_present(slave))
-- mask &= (slave->id[ATA_ID_PIO_MODES] & 0x03);
--
-- /* require pio mode 3 or 4 support for host and all devices */
-- if (mask == 0) {
-- printk(KERN_WARNING "ata%u: no PIO3/4 support, ignoring\n",
-- ap->id);
-- goto err_out;
-+ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
-+ sizeof(model_num));
-+ s = &model_num[0];
-+ len = strnlen(s, sizeof(model_num));
-+
-+ /* ATAPI specifies that empty space is blank-filled; remove blanks */
-+ while ((len > 0) && (s[len - 1] == ' ')) {
-+ len--;
-+ s[len] = 0;
- }
-
-- pio = (mask & ATA_ID_PIO4) ? 4 : 3;
-- for (i = 0; i < ATA_MAX_DEVICES; i++)
-- if (ata_dev_present(&ap->device[i])) {
-- ap->device[i].pio_mode = (pio == 3) ?
-- XFER_PIO_3 : XFER_PIO_4;
-- if (ap->ops->set_piomode)
-- ap->ops->set_piomode(ap, &ap->device[i], pio);
-- }
--
-- return;
-+ for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
-+ if (!strncmp(ata_dma_blacklist[i], s, len))
-+ return 1;
-
--err_out:
-- ap->ops->port_disable(ap);
-+ return 0;
- }
-
--/**
-- * ata_host_set_udma -
-- * @ap:
-- *
-- * LOCKING:
-- */
--
--static void ata_host_set_udma(struct ata_port *ap)
-+static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
- {
- struct ata_device *master, *slave;
-- u16 mask;
-- unsigned int i, j;
-- int udma_mode = -1;
-+ unsigned int mask;
-
- master = &ap->device[0];
- slave = &ap->device[1];
-
- assert (ata_dev_present(master) || ata_dev_present(slave));
-- assert ((ap->flags & ATA_FLAG_PORT_DISABLED) == 0);
-
-- DPRINTK("udma masks: host 0x%X, master 0x%X, slave 0x%X\n",
-- ap->udma_mask,
-- (!ata_dev_present(master)) ? 0xff :
-- (master->id[ATA_ID_UDMA_MODES] & 0xff),
-- (!ata_dev_present(slave)) ? 0xff :
-- (slave->id[ATA_ID_UDMA_MODES] & 0xff));
--
-- mask = ap->udma_mask;
-- if (ata_dev_present(master))
-- mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
-- if (ata_dev_present(slave))
-- mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
--
-- i = XFER_UDMA_7;
-- while (i >= XFER_UDMA_0) {
-- j = i - XFER_UDMA_0;
-- DPRINTK("mask 0x%X i 0x%X j %u\n", mask, i, j);
-- if (mask & (1 << j)) {
-- udma_mode = i;
-- break;
-+ if (shift == ATA_SHIFT_UDMA) {
-+ mask = ap->udma_mask;
-+ if (ata_dev_present(master)) {
-+ mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
-+ if (ata_dma_blacklisted(ap, master)) {
-+ mask = 0;
-+ ata_pr_blacklisted(ap, master);
-+ }
-+ }
-+ if (ata_dev_present(slave)) {
-+ mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
-+ if (ata_dma_blacklisted(ap, slave)) {
-+ mask = 0;
-+ ata_pr_blacklisted(ap, slave);
-+ }
- }
--
-- i--;
- }
--
-- /* require udma for host and all attached devices */
-- if (udma_mode < 0) {
-- printk(KERN_WARNING "ata%u: no UltraDMA support, ignoring\n",
-- ap->id);
-- goto err_out;
-+ else if (shift == ATA_SHIFT_MWDMA) {
-+ mask = ap->mwdma_mask;
-+ if (ata_dev_present(master)) {
-+ mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
-+ if (ata_dma_blacklisted(ap, master)) {
-+ mask = 0;
-+ ata_pr_blacklisted(ap, master);
-+ }
-+ }
-+ if (ata_dev_present(slave)) {
-+ mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
-+ if (ata_dma_blacklisted(ap, slave)) {
-+ mask = 0;
-+ ata_pr_blacklisted(ap, slave);
-+ }
-+ }
- }
--
-- for (i = 0; i < ATA_MAX_DEVICES; i++)
-- if (ata_dev_present(&ap->device[i])) {
-- ap->device[i].udma_mode = udma_mode;
-- if (ap->ops->set_udmamode)
-- ap->ops->set_udmamode(ap, &ap->device[i],
-- udma_mode);
-+ else if (shift == ATA_SHIFT_PIO) {
-+ mask = ap->pio_mask;
-+ if (ata_dev_present(master)) {
-+ /* spec doesn't return explicit support for
-+ * PIO0-2, so we fake it
-+ */
-+ u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
-+ tmp_mode <<= 3;
-+ tmp_mode |= 0x7;
-+ mask &= tmp_mode;
- }
-+ if (ata_dev_present(slave)) {
-+ /* spec doesn't return explicit support for
-+ * PIO0-2, so we fake it
-+ */
-+ u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
-+ tmp_mode <<= 3;
-+ tmp_mode |= 0x7;
-+ mask &= tmp_mode;
-+ }
-+ }
-+ else {
-+ mask = 0xffffffff; /* shut up compiler warning */
-+ BUG();
-+ }
-
-- return;
--
--err_out:
-- ap->ops->port_disable(ap);
-+ return mask;
- }
-
--/**
-- * ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command
-- * @ap: Port associated with device @dev
-- * @dev: Device to which command will be sent
-- *
-- * LOCKING:
-- */
--
--static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
-+/* find greatest bit */
-+static int fgb(u32 bitmap)
- {
-- struct ata_taskfile tf;
--
-- /* set up set-features taskfile */
-- DPRINTK("set features - xfer mode\n");
-- ata_tf_init(ap, &tf, dev->devno);
-- tf.ctl |= ATA_NIEN;
-- tf.command = ATA_CMD_SET_FEATURES;
-- tf.feature = SETFEATURES_XFER;
-- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-- tf.protocol = ATA_PROT_NODATA;
-- if (dev->flags & ATA_DFLAG_PIO)
-- tf.nsect = dev->pio_mode;
-- else
-- tf.nsect = dev->udma_mode;
--
-- /* do bus reset */
-- ata_tf_to_host(ap, &tf);
--
-- /* crazy ATAPI devices... */
-- if (dev->class == ATA_DEV_ATAPI)
-- msleep(150);
--
-- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
--
-- ata_irq_on(ap); /* re-enable interrupts */
-+ unsigned int i;
-+ int x = -1;
-
-- ata_wait_idle(ap);
-+ for (i = 0; i < 32; i++)
-+ if (bitmap & (1 << i))
-+ x = i;
-
-- DPRINTK("EXIT\n");
-+ return x;
- }
-
- /**
-- * ata_dev_set_udma - Set ATA device's transfer mode to Ultra DMA
-- * @ap: Port associated with device @dev
-- * @device: Device whose mode will be set
-+ * ata_choose_xfer_mode - attempt to find best transfer mode
-+ * @ap: Port for which an xfer mode will be selected
-+ * @xfer_mode_out: (output) SET FEATURES - XFER MODE code
-+ * @xfer_shift_out: (output) bit shift that selects this mode
-+ *
-+ * Based on host and device capabilities, determine the
-+ * maximum transfer mode that is amenable to all.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
-+ *
-+ * RETURNS:
-+ * Zero on success, negative on error.
- */
-
--static void ata_dev_set_udma(struct ata_port *ap, unsigned int device)
--{
-- struct ata_device *dev = &ap->device[device];
--
-- if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
-- return;
--
-- ata_dev_set_xfermode(ap, dev);
-+static int ata_choose_xfer_mode(struct ata_port *ap,
-+ u8 *xfer_mode_out,
-+ unsigned int *xfer_shift_out)
-+{
-+ unsigned int mask, shift;
-+ int x, i;
-+
-+ for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
-+ shift = xfer_mode_classes[i].shift;
-+ mask = ata_get_mode_mask(ap, shift);
-+
-+ x = fgb(mask);
-+ if (x >= 0) {
-+ *xfer_mode_out = xfer_mode_classes[i].base + x;
-+ *xfer_shift_out = shift;
-+ return 0;
-+ }
-+ }
-
-- assert((dev->udma_mode >= XFER_UDMA_0) &&
-- (dev->udma_mode <= XFER_UDMA_7));
-- printk(KERN_INFO "ata%u: dev %u configured for %s\n",
-- ap->id, device,
-- udma_str[dev->udma_mode - XFER_UDMA_0]);
-+ return -1;
- }
-
- /**
-- * ata_dev_set_pio - Set ATA device's transfer mode to PIO
-+ * ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command
- * @ap: Port associated with device @dev
-- * @device: Device whose mode will be set
-+ * @dev: Device to which command will be sent
-+ *
-+ * Issue SET FEATURES - XFER MODE command to device @dev
-+ * on port @ap.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- */
-
--static void ata_dev_set_pio(struct ata_port *ap, unsigned int device)
-+static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
- {
-- struct ata_device *dev = &ap->device[device];
-+ DECLARE_COMPLETION(wait);
-+ struct ata_queued_cmd *qc;
-+ int rc;
-+ unsigned long flags;
-
-- if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
-- return;
-+ /* set up set-features taskfile */
-+ DPRINTK("set features - xfer mode\n");
-
-- /* force PIO mode */
-- dev->flags |= ATA_DFLAG_PIO;
-+ qc = ata_qc_new_init(ap, dev);
-+ BUG_ON(qc == NULL);
-
-- ata_dev_set_xfermode(ap, dev);
-+ qc->tf.command = ATA_CMD_SET_FEATURES;
-+ qc->tf.feature = SETFEATURES_XFER;
-+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-+ qc->tf.protocol = ATA_PROT_NODATA;
-+ qc->tf.nsect = dev->xfer_mode;
-+
-+ qc->waiting = &wait;
-+ qc->complete_fn = ata_qc_complete_noop;
-+
-+ spin_lock_irqsave(&ap->host_set->lock, flags);
-+ rc = ata_qc_issue(qc);
-+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-- assert((dev->pio_mode >= XFER_PIO_3) &&
-- (dev->pio_mode <= XFER_PIO_4));
-- printk(KERN_INFO "ata%u: dev %u configured for PIO%c\n",
-- ap->id, device,
-- dev->pio_mode == 3 ? '3' : '4');
-+ if (rc)
-+ ata_port_disable(ap);
-+ else
-+ wait_for_completion(&wait);
-+
-+ DPRINTK("EXIT\n");
- }
-
- /**
-- * ata_sg_clean -
-- * @qc:
-+ * ata_sg_clean - Unmap DMA memory associated with command
-+ * @qc: Command containing DMA memory to be released
-+ *
-+ * Unmap all mapped DMA memory associated with this command.
- *
- * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
- */
-
- static void ata_sg_clean(struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- struct scatterlist *sg = qc->sg;
-- int dir = qc->pci_dma_dir;
-+ int dir = qc->dma_dir;
-
- assert(qc->flags & ATA_QCFLAG_DMAMAP);
- assert(sg != NULL);
-@@ -1762,9 +2154,9 @@ static void ata_sg_clean(struct ata_queu
- DPRINTK("unmapping %u sg elements\n", qc->n_elem);
-
- if (qc->flags & ATA_QCFLAG_SG)
-- pci_unmap_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
-+ dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
- else
-- pci_unmap_single(ap->host_set->pdev, sg_dma_address(&sg[0]),
-+ dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
- sg_dma_len(&sg[0]), dir);
-
- qc->flags &= ~ATA_QCFLAG_DMAMAP;
-@@ -1775,7 +2167,11 @@ static void ata_sg_clean(struct ata_queu
- * ata_fill_sg - Fill PCI IDE PRD table
- * @qc: Metadata associated with taskfile to be transferred
- *
-+ * Fill PCI IDE PRD (scatter-gather) table with segments
-+ * associated with the current disk command.
-+ *
- * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
- *
- */
- static void ata_fill_sg(struct ata_queued_cmd *qc)
-@@ -1789,7 +2185,7 @@ static void ata_fill_sg(struct ata_queue
-
- idx = 0;
- for (nelem = qc->n_elem; nelem; nelem--,sg++) {
-- u32 addr, boundary;
-+ u32 addr, offset;
- u32 sg_len, len;
-
- /* determine if physical DMA addr spans 64K boundary.
-@@ -1800,10 +2196,10 @@ static void ata_fill_sg(struct ata_queue
- sg_len = sg_dma_len(sg);
-
- while (sg_len) {
-- boundary = (addr & ~0xffff) + (0xffff + 1);
-+ offset = addr & 0xffff;
- len = sg_len;
-- if ((addr + sg_len) > boundary)
-- len = boundary - addr;
-+ if ((offset + sg_len) > 0x10000)
-+ len = 0x10000 - offset;
-
- ap->prd[idx].addr = cpu_to_le32(addr);
- ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
-@@ -1818,11 +2214,36 @@ static void ata_fill_sg(struct ata_queue
- if (idx)
- ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
- }
-+/**
-+ * ata_check_atapi_dma - Check whether ATAPI DMA can be supported
-+ * @qc: Metadata associated with taskfile to check
-+ *
-+ * Allow low-level driver to filter ATA PACKET commands, returning
-+ * a status indicating whether or not it is OK to use DMA for the
-+ * supplied PACKET command.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ *
-+ * RETURNS: 0 when ATAPI DMA can be used
-+ * nonzero otherwise
-+ */
-+int ata_check_atapi_dma(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ int rc = 0; /* Assume ATAPI DMA is OK by default */
-+
-+ if (ap->ops->check_atapi_dma)
-+ rc = ap->ops->check_atapi_dma(qc);
-
-+ return rc;
-+}
- /**
- * ata_qc_prep - Prepare taskfile for submission
- * @qc: Metadata associated with taskfile to be prepared
- *
-+ * Prepare ATA taskfile for submission.
-+ *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- */
-@@ -1834,6 +2255,32 @@ void ata_qc_prep(struct ata_queued_cmd *
- ata_fill_sg(qc);
- }
-
-+/**
-+ * ata_sg_init_one - Associate command with memory buffer
-+ * @qc: Command to be associated
-+ * @buf: Memory buffer
-+ * @buflen: Length of memory buffer, in bytes.
-+ *
-+ * Initialize the data-related elements of queued_cmd @qc
-+ * to point to a single memory buffer, @buf of byte length @buflen.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+
-+
-+/**
-+ * ata_sg_init_one - Prepare a one-entry scatter-gather list.
-+ * @qc: Queued command
-+ * @buf: transfer buffer
-+ * @buflen: length of buf
-+ *
-+ * Builds a single-entry scatter-gather list to initiate a
-+ * transfer utilizing the specified buffer.
-+ *
-+ * LOCKING:
-+ */
- void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
- {
- struct scatterlist *sg;
-@@ -1848,11 +2295,35 @@ void ata_sg_init_one(struct ata_queued_c
- sg = qc->sg;
- sg->page = virt_to_page(buf);
- sg->offset = (unsigned long) buf & ~PAGE_MASK;
-- sg_dma_len(sg) = buflen;
--
-- WARN_ON(buflen > PAGE_SIZE);
-+ sg->length = buflen;
- }
-
-+/**
-+ * ata_sg_init - Associate command with scatter-gather table.
-+ * @qc: Command to be associated
-+ * @sg: Scatter-gather table.
-+ * @n_elem: Number of elements in s/g table.
-+ *
-+ * Initialize the data-related elements of queued_cmd @qc
-+ * to point to a scatter-gather table @sg, containing @n_elem
-+ * elements.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+
-+/**
-+ * ata_sg_init - Assign a scatter gather list to a queued command
-+ * @qc: Queued command
-+ * @sg: Scatter-gather list
-+ * @n_elem: length of sg list
-+ *
-+ * Attaches a scatter-gather list to a queued command.
-+ *
-+ * LOCKING:
-+ */
-+
- void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
- unsigned int n_elem)
- {
-@@ -1862,29 +2333,32 @@ void ata_sg_init(struct ata_queued_cmd *
- }
-
- /**
-- * ata_sg_setup_one -
-- * @qc:
-+ * ata_sg_setup_one - DMA-map the memory buffer associated with a command.
-+ * @qc: Command with memory buffer to be mapped.
-+ *
-+ * DMA-map the memory buffer associated with queued_cmd @qc.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- *
- * RETURNS:
-- *
-+ * Zero on success, negative on error.
- */
-
- static int ata_sg_setup_one(struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
-- int dir = qc->pci_dma_dir;
-+ int dir = qc->dma_dir;
- struct scatterlist *sg = qc->sg;
- dma_addr_t dma_address;
-
-- dma_address = pci_map_single(ap->host_set->pdev, qc->buf_virt,
-- sg_dma_len(sg), dir);
-- if (pci_dma_mapping_error(dma_address))
-+ dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
-+ sg->length, dir);
-+ if (dma_mapping_error(dma_address))
- return -1;
-
- sg_dma_address(sg) = dma_address;
-+ sg_dma_len(sg) = sg->length;
-
- DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
- qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-@@ -1893,13 +2367,16 @@ static int ata_sg_setup_one(struct ata_q
- }
-
- /**
-- * ata_sg_setup -
-- * @qc:
-+ * ata_sg_setup - DMA-map the scatter-gather table associated with a command.
-+ * @qc: Command with scatter-gather table to be mapped.
-+ *
-+ * DMA-map the scatter-gather table associated with queued_cmd @qc.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- *
- * RETURNS:
-+ * Zero on success, negative on error.
- *
- */
-
-@@ -1912,8 +2389,8 @@ static int ata_sg_setup(struct ata_queue
- VPRINTK("ENTER, ata%u\n", ap->id);
- assert(qc->flags & ATA_QCFLAG_SG);
-
-- dir = qc->pci_dma_dir;
-- n_elem = pci_map_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
-+ dir = qc->dma_dir;
-+ n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
- if (n_elem < 1)
- return -1;
-
-@@ -1929,6 +2406,7 @@ static int ata_sg_setup(struct ata_queue
- * @ap:
- *
- * LOCKING:
-+ * None. (executing in kernel thread context)
- *
- * RETURNS:
- *
-@@ -1976,6 +2454,7 @@ static unsigned long ata_pio_poll(struct
- * @ap:
- *
- * LOCKING:
-+ * None. (executing in kernel thread context)
- */
-
- static void ata_pio_complete (struct ata_port *ap)
-@@ -2003,7 +2482,7 @@ static void ata_pio_complete (struct ata
- }
-
- drv_stat = ata_wait_idle(ap);
-- if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
-+ if (!ata_ok(drv_stat)) {
- ap->pio_task_state = PIO_ST_ERR;
- return;
- }
-@@ -2018,19 +2497,197 @@ static void ata_pio_complete (struct ata
- ata_qc_complete(qc, drv_stat);
- }
-
-+
-+/**
-+ * swap_buf_le16 -
-+ * @buf: Buffer to swap
-+ * @buf_words: Number of 16-bit words in buffer.
-+ *
-+ * Swap halves of 16-bit words if needed to convert from
-+ * little-endian byte order to native cpu byte order, or
-+ * vice-versa.
-+ *
-+ * LOCKING:
-+ */
-+void swap_buf_le16(u16 *buf, unsigned int buf_words)
-+{
-+#ifdef __BIG_ENDIAN
-+ unsigned int i;
-+
-+ for (i = 0; i < buf_words; i++)
-+ buf[i] = le16_to_cpu(buf[i]);
-+#endif /* __BIG_ENDIAN */
-+}
-+
-+static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
-+ unsigned int buflen, int write_data)
-+{
-+ unsigned int i;
-+ unsigned int words = buflen >> 1;
-+ u16 *buf16 = (u16 *) buf;
-+ void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
-+
-+ if (write_data) {
-+ for (i = 0; i < words; i++)
-+ writew(le16_to_cpu(buf16[i]), mmio);
-+ } else {
-+ for (i = 0; i < words; i++)
-+ buf16[i] = cpu_to_le16(readw(mmio));
-+ }
-+}
-+
-+static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
-+ unsigned int buflen, int write_data)
-+{
-+ unsigned int dwords = buflen >> 1;
-+
-+ if (write_data)
-+ outsw(ap->ioaddr.data_addr, buf, dwords);
-+ else
-+ insw(ap->ioaddr.data_addr, buf, dwords);
-+}
-+
-+static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
-+ unsigned int buflen, int do_write)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO)
-+ ata_mmio_data_xfer(ap, buf, buflen, do_write);
-+ else
-+ ata_pio_data_xfer(ap, buf, buflen, do_write);
-+}
-+
-+static void ata_pio_sector(struct ata_queued_cmd *qc)
-+{
-+ int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-+ struct scatterlist *sg = qc->sg;
-+ struct ata_port *ap = qc->ap;
-+ struct page *page;
-+ unsigned int offset;
-+ unsigned char *buf;
-+
-+ if (qc->cursect == (qc->nsect - 1))
-+ ap->pio_task_state = PIO_ST_LAST;
-+
-+ page = sg[qc->cursg].page;
-+ offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
-+
-+ /* get the current page and offset */
-+ page = nth_page(page, (offset >> PAGE_SHIFT));
-+ offset %= PAGE_SIZE;
-+
-+ buf = kmap(page) + offset;
-+
-+ qc->cursect++;
-+ qc->cursg_ofs++;
-+
-+ if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
-+ qc->cursg++;
-+ qc->cursg_ofs = 0;
-+ }
-+
-+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-+
-+ /* do the actual data transfer */
-+ do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-+ ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
-+
-+ kunmap(page);
-+}
-+
-+static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
-+{
-+ int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-+ struct scatterlist *sg = qc->sg;
-+ struct ata_port *ap = qc->ap;
-+ struct page *page;
-+ unsigned char *buf;
-+ unsigned int offset, count;
-+
-+ if (qc->curbytes == qc->nbytes - bytes)
-+ ap->pio_task_state = PIO_ST_LAST;
-+
-+next_sg:
-+ sg = &qc->sg[qc->cursg];
-+
-+ page = sg->page;
-+ offset = sg->offset + qc->cursg_ofs;
-+
-+ /* get the current page and offset */
-+ page = nth_page(page, (offset >> PAGE_SHIFT));
-+ offset %= PAGE_SIZE;
-+
-+ /* don't overrun current sg */
-+ count = min(sg->length - qc->cursg_ofs, bytes);
-+
-+ /* don't cross page boundaries */
-+ count = min(count, (unsigned int)PAGE_SIZE - offset);
-+
-+ buf = kmap(page) + offset;
-+
-+ bytes -= count;
-+ qc->curbytes += count;
-+ qc->cursg_ofs += count;
-+
-+ if (qc->cursg_ofs == sg->length) {
-+ qc->cursg++;
-+ qc->cursg_ofs = 0;
-+ }
-+
-+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-+
-+ /* do the actual data transfer */
-+ ata_data_xfer(ap, buf, count, do_write);
-+
-+ kunmap(page);
-+
-+ if (bytes) {
-+ goto next_sg;
-+ }
-+}
-+
-+static void atapi_pio_bytes(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ struct ata_device *dev = qc->dev;
-+ unsigned int ireason, bc_lo, bc_hi, bytes;
-+ int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
-+
-+ ap->ops->tf_read(ap, &qc->tf);
-+ ireason = qc->tf.nsect;
-+ bc_lo = qc->tf.lbam;
-+ bc_hi = qc->tf.lbah;
-+ bytes = (bc_hi << 8) | bc_lo;
-+
-+ /* shall be cleared to zero, indicating xfer of data */
-+ if (ireason & (1 << 0))
-+ goto err_out;
-+
-+ /* make sure transfer direction matches expected */
-+ i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
-+ if (do_write != i_write)
-+ goto err_out;
-+
-+ __atapi_pio_bytes(qc, bytes);
-+
-+ return;
-+
-+err_out:
-+ printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
-+ ap->id, dev->devno);
-+ ap->pio_task_state = PIO_ST_ERR;
-+}
-+
- /**
- * ata_pio_sector -
- * @ap:
- *
- * LOCKING:
-+ * None. (executing in kernel thread context)
- */
-
--static void ata_pio_sector(struct ata_port *ap)
-+static void ata_pio_block(struct ata_port *ap)
- {
- struct ata_queued_cmd *qc;
-- struct scatterlist *sg;
-- struct page *page;
-- unsigned char *buf;
- u8 status;
-
- /*
-@@ -2052,55 +2709,62 @@ static void ata_pio_sector(struct ata_po
- }
- }
-
-- /* handle BSY=0, DRQ=0 as error */
-- if ((status & ATA_DRQ) == 0) {
-- ap->pio_task_state = PIO_ST_ERR;
-- return;
-- }
--
- qc = ata_qc_from_tag(ap, ap->active_tag);
- assert(qc != NULL);
-
-- sg = qc->sg;
-+ if (is_atapi_taskfile(&qc->tf)) {
-+ /* no more data to transfer or unsupported ATAPI command */
-+ if ((status & ATA_DRQ) == 0) {
-+ ap->pio_task_state = PIO_ST_IDLE;
-
-- if (qc->cursect == (qc->nsect - 1))
-- ap->pio_task_state = PIO_ST_LAST;
-+ ata_irq_on(ap);
-
-- page = sg[qc->cursg].page;
-- buf = kmap(page) +
-- sg[qc->cursg].offset + (qc->cursg_ofs * ATA_SECT_SIZE);
--
-- qc->cursect++;
-- qc->cursg_ofs++;
-+ ata_qc_complete(qc, status);
-+ return;
-+ }
-
-- if (qc->flags & ATA_QCFLAG_SG)
-- if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
-- qc->cursg++;
-- qc->cursg_ofs = 0;
-+ atapi_pio_bytes(qc);
-+ } else {
-+ /* handle BSY=0, DRQ=0 as error */
-+ if ((status & ATA_DRQ) == 0) {
-+ ap->pio_task_state = PIO_ST_ERR;
-+ return;
- }
-
-- DPRINTK("data %s, drv_stat 0x%X\n",
-- qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read",
-- status);
-+ ata_pio_sector(qc);
-+ }
-+}
-
-- /* do the actual data transfer */
-- /* FIXME: mmio-ize */
-- if (qc->tf.flags & ATA_TFLAG_WRITE)
-- outsl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
-- else
-- insl(ap->ioaddr.data_addr, buf, ATA_SECT_DWORDS);
-+static void ata_pio_error(struct ata_port *ap)
-+{
-+ struct ata_queued_cmd *qc;
-+ u8 drv_stat;
-
-- kunmap(page);
-+ qc = ata_qc_from_tag(ap, ap->active_tag);
-+ assert(qc != NULL);
-+
-+ drv_stat = ata_chk_status(ap);
-+ printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
-+ ap->id, drv_stat);
-+
-+ ap->pio_task_state = PIO_ST_IDLE;
-+
-+ ata_irq_on(ap);
-+
-+ ata_qc_complete(qc, drv_stat | ATA_ERR);
- }
-
--static void ata_pio_task(void *_data)
-+void ata_pio_task(void *_data)
- {
- struct ata_port *ap = _data;
- unsigned long timeout = 0;
-
- switch (ap->pio_task_state) {
-+ case PIO_ST_IDLE:
-+ return;
-+
- case PIO_ST:
-- ata_pio_sector(ap);
-+ ata_pio_block(ap);
- break;
-
- case PIO_ST_LAST:
-@@ -2113,27 +2777,62 @@ static void ata_pio_task(void *_data)
- break;
-
- case PIO_ST_TMOUT:
-- printk(KERN_ERR "ata%d: FIXME: PIO_ST_TMOUT\n", /* FIXME */
-- ap->id);
-- timeout = 11 * HZ;
-- break;
--
- case PIO_ST_ERR:
-- printk(KERN_ERR "ata%d: FIXME: PIO_ST_ERR\n", /* FIXME */
-- ap->id);
-- timeout = 11 * HZ;
-- break;
-+ ata_pio_error(ap);
-+ return;
- }
-
-- if ((ap->pio_task_state != PIO_ST_IDLE) &&
-- (ap->pio_task_state != PIO_ST_TMOUT) &&
-- (ap->pio_task_state != PIO_ST_ERR)) {
-- if (timeout)
-- queue_delayed_work(ata_wq, &ap->pio_task,
-- timeout);
-- else
-- queue_work(ata_wq, &ap->pio_task);
-- }
-+ if (timeout)
-+ queue_delayed_work(ata_wq, &ap->pio_task,
-+ timeout);
-+ else
-+ queue_work(ata_wq, &ap->pio_task);
-+}
-+
-+static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
-+ struct scsi_cmnd *cmd)
-+{
-+ DECLARE_COMPLETION(wait);
-+ struct ata_queued_cmd *qc;
-+ unsigned long flags;
-+ int rc;
-+
-+ DPRINTK("ATAPI request sense\n");
-+
-+ qc = ata_qc_new_init(ap, dev);
-+ BUG_ON(qc == NULL);
-+
-+ /* FIXME: is this needed? */
-+ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-+
-+ ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
-+ qc->dma_dir = DMA_FROM_DEVICE;
-+
-+ memset(&qc->cdb, 0, ap->cdb_len);
-+ qc->cdb[0] = REQUEST_SENSE;
-+ qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
-+
-+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-+ qc->tf.command = ATA_CMD_PACKET;
-+
-+ qc->tf.protocol = ATA_PROT_ATAPI;
-+ qc->tf.lbam = (8 * 1024) & 0xff;
-+ qc->tf.lbah = (8 * 1024) >> 8;
-+ qc->nbytes = SCSI_SENSE_BUFFERSIZE;
-+
-+ qc->waiting = &wait;
-+ qc->complete_fn = ata_qc_complete_noop;
-+
-+ spin_lock_irqsave(&ap->host_set->lock, flags);
-+ rc = ata_qc_issue(qc);
-+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
-+
-+ if (rc)
-+ ata_port_disable(ap);
-+ else
-+ wait_for_completion(&wait);
-+
-+ DPRINTK("EXIT\n");
- }
-
- /**
-@@ -2152,15 +2851,35 @@ static void ata_pio_task(void *_data)
- * transaction completed successfully.
- *
- * LOCKING:
-+ * Inherited from SCSI layer (none, can sleep)
- */
-
- static void ata_qc_timeout(struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
-+ struct ata_device *dev = qc->dev;
- u8 host_stat = 0, drv_stat;
-
- DPRINTK("ENTER\n");
-
-+ /* FIXME: doesn't this conflict with timeout handling? */
-+ if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
-+ struct scsi_cmnd *cmd = qc->scsicmd;
-+
-+ if (!scsi_eh_eflags_chk(cmd, SCSI_EH_CANCEL_CMD)) {
-+
-+ /* finish completing original command */
-+ __ata_qc_complete(qc);
-+
-+ atapi_request_sense(ap, dev, cmd);
-+
-+ cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
-+ scsi_finish_command(cmd);
-+
-+ goto out;
-+ }
-+ }
-+
- /* hack alert! We cannot use the supplied completion
- * function from inside the ->eh_strategy_handler() thread.
- * libata is the only user of ->eh_strategy_handler() in
-@@ -2173,20 +2892,19 @@ static void ata_qc_timeout(struct ata_qu
-
- case ATA_PROT_DMA:
- case ATA_PROT_ATAPI_DMA:
-- host_stat = ata_bmdma_status(ap);
-+ host_stat = ap->ops->bmdma_status(ap);
-
- /* before we do anything else, clear DMA-Start bit */
-- ata_bmdma_stop(ap);
-+ ap->ops->bmdma_stop(ap);
-
- /* fall through */
-
-- case ATA_PROT_NODATA:
- default:
- ata_altstatus(ap);
- drv_stat = ata_chk_status(ap);
-
- /* ack bmdma irq events */
-- ata_bmdma_ack_irq(ap);
-+ ap->ops->irq_clear(ap);
-
- printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
- ap->id, qc->tf.command, drv_stat, host_stat);
-@@ -2195,7 +2913,7 @@ static void ata_qc_timeout(struct ata_qu
- ata_qc_complete(qc, drv_stat);
- break;
- }
--
-+out:
- DPRINTK("EXIT\n");
- }
-
-@@ -2243,6 +2961,7 @@ out:
- * @dev: Device from whom we request an available command structure
- *
- * LOCKING:
-+ * None.
- */
-
- static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
-@@ -2268,6 +2987,7 @@ static struct ata_queued_cmd *ata_qc_new
- * @dev: Device from whom we request an available command structure
- *
- * LOCKING:
-+ * None.
- */
-
- struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
-@@ -2284,31 +3004,80 @@ struct ata_queued_cmd *ata_qc_new_init(s
- qc->dev = dev;
- qc->cursect = qc->cursg = qc->cursg_ofs = 0;
- qc->nsect = 0;
-+ qc->nbytes = qc->curbytes = 0;
-
- ata_tf_init(ap, &qc->tf, dev->devno);
-
-- if (likely((dev->flags & ATA_DFLAG_PIO) == 0))
-- qc->flags |= ATA_QCFLAG_DMA;
- if (dev->flags & ATA_DFLAG_LBA48)
- qc->tf.flags |= ATA_TFLAG_LBA48;
- }
-
-- return qc;
-+ return qc;
-+}
-+
-+static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
-+{
-+ return 0;
-+}
-+
-+static void __ata_qc_complete(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ unsigned int tag, do_clear = 0;
-+
-+ qc->flags = 0;
-+ tag = qc->tag;
-+ if (likely(ata_tag_valid(tag))) {
-+ if (tag == ap->active_tag)
-+ ap->active_tag = ATA_TAG_POISON;
-+ qc->tag = ATA_TAG_POISON;
-+ do_clear = 1;
-+ }
-+
-+ if (qc->waiting) {
-+ struct completion *waiting = qc->waiting;
-+ qc->waiting = NULL;
-+ complete(waiting);
-+ }
-+
-+ if (likely(do_clear))
-+ clear_bit(tag, &ap->qactive);
-+}
-+
-+/**
-+ * ata_qc_free - free unused ata_queued_cmd
-+ * @qc: Command to complete
-+ *
-+ * Designed to free unused ata_queued_cmd object
-+ * in case something prevents using it.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ *
-+ */
-+void ata_qc_free(struct ata_queued_cmd *qc)
-+{
-+ assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
-+ assert(qc->waiting == NULL); /* nothing should be waiting */
-+
-+ __ata_qc_complete(qc);
- }
-
- /**
- * ata_qc_complete - Complete an active ATA command
- * @qc: Command to complete
-- * @drv_stat: ATA status register contents
-+ * @drv_stat: ATA Status register contents
-+ *
-+ * Indicate to the mid and upper layers that an ATA
-+ * command has completed, with either an ok or not-ok status.
- *
- * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
- *
- */
-
- void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
- {
-- struct ata_port *ap = qc->ap;
-- unsigned int tag, do_clear = 0;
- int rc;
-
- assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
-@@ -2319,6 +3088,7 @@ void ata_qc_complete(struct ata_queued_c
-
- /* call completion callback */
- rc = qc->complete_fn(qc, drv_stat);
-+ qc->flags &= ~ATA_QCFLAG_ACTIVE;
-
- /* if callback indicates not to complete command (non-zero),
- * return immediately
-@@ -2326,20 +3096,33 @@ void ata_qc_complete(struct ata_queued_c
- if (rc != 0)
- return;
-
-- qc->flags = 0;
-- tag = qc->tag;
-- if (likely(ata_tag_valid(tag))) {
-- if (tag == ap->active_tag)
-- ap->active_tag = ATA_TAG_POISON;
-- qc->tag = ATA_TAG_POISON;
-- do_clear = 1;
-- }
-+ __ata_qc_complete(qc);
-
-- if (qc->waiting)
-- complete(qc->waiting);
-+ VPRINTK("EXIT\n");
-+}
-
-- if (likely(do_clear))
-- clear_bit(tag, &ap->qactive);
-+static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+
-+ switch (qc->tf.protocol) {
-+ case ATA_PROT_DMA:
-+ case ATA_PROT_ATAPI_DMA:
-+ return 1;
-+
-+ case ATA_PROT_ATAPI:
-+ case ATA_PROT_PIO:
-+ case ATA_PROT_PIO_MULT:
-+ if (ap->flags & ATA_FLAG_PIO_DMA)
-+ return 1;
-+
-+ /* fall through */
-+
-+ default:
-+ return 0;
-+ }
-+
-+ /* never reached */
- }
-
- /**
-@@ -2362,12 +3145,16 @@ int ata_qc_issue(struct ata_queued_cmd *
- {
- struct ata_port *ap = qc->ap;
-
-- if (qc->flags & ATA_QCFLAG_SG) {
-- if (ata_sg_setup(qc))
-- goto err_out;
-- } else if (qc->flags & ATA_QCFLAG_SINGLE) {
-- if (ata_sg_setup_one(qc))
-- goto err_out;
-+ if (ata_should_dma_map(qc)) {
-+ if (qc->flags & ATA_QCFLAG_SG) {
-+ if (ata_sg_setup(qc))
-+ goto err_out;
-+ } else if (qc->flags & ATA_QCFLAG_SINGLE) {
-+ if (ata_sg_setup_one(qc))
-+ goto err_out;
-+ }
-+ } else {
-+ qc->flags &= ~ATA_QCFLAG_DMAMAP;
- }
-
- ap->ops->qc_prep(qc);
-@@ -2381,6 +3168,7 @@ err_out:
- return -1;
- }
-
-+
- /**
- * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
- * @qc: command to issue to device
-@@ -2390,6 +3178,8 @@ err_out:
- * classes called "protocols", and issuing each type of protocol
- * is slightly different.
- *
-+ * May be used as the qc_issue() entry in ata_port_operations.
-+ *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- *
-@@ -2422,6 +3212,12 @@ int ata_qc_issue_prot(struct ata_queued_
- break;
-
- case ATA_PROT_ATAPI:
-+ ata_qc_set_polling(qc);
-+ ata_tf_to_host_nolock(ap, &qc->tf);
-+ queue_work(ata_wq, &ap->packet_task);
-+ break;
-+
-+ case ATA_PROT_ATAPI_NODATA:
- ata_tf_to_host_nolock(ap, &qc->tf);
- queue_work(ata_wq, &ap->packet_task);
- break;
-@@ -2441,19 +3237,19 @@ int ata_qc_issue_prot(struct ata_queued_
- }
-
- /**
-- * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
-+ * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
-+static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 dmactl;
-- void *mmio = (void *) ap->ioaddr.bmdma_addr;
-+ void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-
- /* load PRD table addr. */
- mb(); /* make sure PRD table writes are visible to controller */
-@@ -2471,17 +3267,17 @@ void ata_bmdma_setup_mmio (struct ata_qu
- }
-
- /**
-- * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
-+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
-+static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
-- void *mmio = (void *) ap->ioaddr.bmdma_addr;
-+ void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
- u8 dmactl;
-
- /* start host DMA transaction */
-@@ -2509,7 +3305,7 @@ void ata_bmdma_start_mmio (struct ata_qu
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
-+static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
-@@ -2537,7 +3333,7 @@ void ata_bmdma_setup_pio (struct ata_que
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
-+static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- u8 dmactl;
-@@ -2548,9 +3344,126 @@ void ata_bmdma_start_pio (struct ata_que
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- }
-
-+
-+/**
-+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
-+ * @qc: Info associated with this ATA transaction.
-+ *
-+ * Writes the ATA_DMA_START flag to the DMA command register.
-+ *
-+ * May be used as the bmdma_start() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+void ata_bmdma_start(struct ata_queued_cmd *qc)
-+{
-+ if (qc->ap->flags & ATA_FLAG_MMIO)
-+ ata_bmdma_start_mmio(qc);
-+ else
-+ ata_bmdma_start_pio(qc);
-+}
-+
-+
-+/**
-+ * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
-+ * @qc: Info associated with this ATA transaction.
-+ *
-+ * Writes address of PRD table to device's PRD Table Address
-+ * register, sets the DMA control register, and calls
-+ * ops->exec_command() to start the transfer.
-+ *
-+ * May be used as the bmdma_setup() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+void ata_bmdma_setup(struct ata_queued_cmd *qc)
-+{
-+ if (qc->ap->flags & ATA_FLAG_MMIO)
-+ ata_bmdma_setup_mmio(qc);
-+ else
-+ ata_bmdma_setup_pio(qc);
-+}
-+
-+
-+/**
-+ * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
-+ * @ap: Port associated with this ATA transaction.
-+ *
-+ * Clear interrupt and error flags in DMA status register.
-+ *
-+ * May be used as the irq_clear() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
- void ata_bmdma_irq_clear(struct ata_port *ap)
- {
-- ata_bmdma_ack_irq(ap);
-+ if (ap->flags & ATA_FLAG_MMIO) {
-+ void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
-+ writeb(readb(mmio), mmio);
-+ } else {
-+ unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
-+ outb(inb(addr), addr);
-+ }
-+
-+}
-+
-+
-+/**
-+ * ata_bmdma_status - Read PCI IDE BMDMA status
-+ * @ap: Port associated with this ATA transaction.
-+ *
-+ * Read and return BMDMA status register.
-+ *
-+ * May be used as the bmdma_status() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+u8 ata_bmdma_status(struct ata_port *ap)
-+{
-+ u8 host_stat;
-+ if (ap->flags & ATA_FLAG_MMIO) {
-+ void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-+ host_stat = readb(mmio + ATA_DMA_STATUS);
-+ } else
-+ host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-+ return host_stat;
-+}
-+
-+
-+/**
-+ * ata_bmdma_stop - Stop PCI IDE BMDMA transfer
-+ * @ap: Port associated with this ATA transaction.
-+ *
-+ * Clears the ATA_DMA_START flag in the dma control register
-+ *
-+ * May be used as the bmdma_stop() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ */
-+
-+void ata_bmdma_stop(struct ata_port *ap)
-+{
-+ if (ap->flags & ATA_FLAG_MMIO) {
-+ void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-+
-+ /* clear start/stop bit */
-+ writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
-+ mmio + ATA_DMA_CMD);
-+ } else {
-+ /* clear start/stop bit */
-+ outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
-+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-+ }
-+
-+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-+ ata_altstatus(ap); /* dummy read */
- }
-
- /**
-@@ -2580,18 +3493,19 @@ inline unsigned int ata_host_intr (struc
- case ATA_PROT_ATAPI_DMA:
- case ATA_PROT_ATAPI:
- /* check status of DMA engine */
-- host_stat = ata_bmdma_status(ap);
-- VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat);
-+ host_stat = ap->ops->bmdma_status(ap);
-+ VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
-
- /* if it's not our irq... */
- if (!(host_stat & ATA_DMA_INTR))
- goto idle_irq;
-
- /* before we do anything else, clear DMA-Start bit */
-- ata_bmdma_stop(ap);
-+ ap->ops->bmdma_stop(ap);
-
- /* fall through */
-
-+ case ATA_PROT_ATAPI_NODATA:
- case ATA_PROT_NODATA:
- /* check altstatus */
- status = ata_altstatus(ap);
-@@ -2602,10 +3516,11 @@ inline unsigned int ata_host_intr (struc
- status = ata_chk_status(ap);
- if (unlikely(status & ATA_BUSY))
- goto idle_irq;
-- DPRINTK("BUS_NODATA (dev_stat 0x%X)\n", status);
-+ DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
-+ ap->id, qc->tf.protocol, status);
-
- /* ack bmdma irq events */
-- ata_bmdma_ack_irq(ap);
-+ ap->ops->irq_clear(ap);
-
- /* complete taskfile transaction */
- ata_qc_complete(qc, status);
-@@ -2632,13 +3547,18 @@ idle_irq:
-
- /**
- * ata_interrupt - Default ATA host interrupt handler
-- * @irq: irq line
-- * @dev_instance: pointer to our host information structure
-+ * @irq: irq line (unused)
-+ * @dev_instance: pointer to our ata_host_set information structure
- * @regs: unused
- *
-+ * Default interrupt handler for PCI IDE devices. Calls
-+ * ata_host_intr() for each port that is not disabled.
-+ *
- * LOCKING:
-+ * Obtains host_set lock during operation.
- *
- * RETURNS:
-+ * IRQ_NONE or IRQ_HANDLED.
- *
- */
-
-@@ -2660,7 +3580,8 @@ irqreturn_t ata_interrupt (int irq, void
- struct ata_queued_cmd *qc;
-
- qc = ata_qc_from_tag(ap, ap->active_tag);
-- if (qc && (!(qc->tf.ctl & ATA_NIEN)))
-+ if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
-+ (qc->flags & ATA_QCFLAG_ACTIVE))
- handled |= ata_host_intr(ap, qc);
- }
- }
-@@ -2701,21 +3622,20 @@ static void atapi_packet_task(void *_dat
-
- /* make sure DRQ is set */
- status = ata_chk_status(ap);
-- if ((status & ATA_DRQ) == 0)
-+ if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
- goto err_out;
-
- /* send SCSI cdb */
-- /* FIXME: mmio-ize */
- DPRINTK("send cdb\n");
-- outsl(ap->ioaddr.data_addr,
-- qc->scsicmd->cmnd, ap->host->max_cmd_len / 4);
-+ assert(ap->cdb_len >= 12);
-+ ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
-
- /* if we are DMA'ing, irq handler takes over from here */
- if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
- ap->ops->bmdma_start(qc); /* initiate bmdma */
-
- /* non-data commands are also handled via irq */
-- else if (qc->scsicmd->sc_data_direction == SCSI_DATA_NONE) {
-+ else if (qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
- /* do nothing */
- }
-
-@@ -2731,11 +3651,24 @@ err_out:
- ata_qc_complete(qc, ATA_ERR);
- }
-
-+
-+/**
-+ * ata_port_start - Set port up for dma.
-+ * @ap: Port to initialize
-+ *
-+ * Called just after data structures for each port are
-+ * initialized. Allocates space for PRD table.
-+ *
-+ * May be used as the port_start() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ */
-+
- int ata_port_start (struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
-
-- ap->prd = pci_alloc_consistent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma);
-+ ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
- if (!ap->prd)
- return -ENOMEM;
-
-@@ -2744,13 +3677,32 @@ int ata_port_start (struct ata_port *ap)
- return 0;
- }
-
-+
-+/**
-+ * ata_port_stop - Undo ata_port_start()
-+ * @ap: Port to shut down
-+ *
-+ * Frees the PRD table.
-+ *
-+ * May be used as the port_stop() entry in ata_port_operations.
-+ *
-+ * LOCKING:
-+ */
-+
- void ata_port_stop (struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
-+
-+ dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
-+}
-
-- pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
-+void ata_host_stop (struct ata_host_set *host_set)
-+{
-+ if (host_set->mmio_base)
-+ iounmap(host_set->mmio_base);
- }
-
-+
- /**
- * ata_host_remove - Unregister SCSI host structure with upper layers
- * @ap: Port to unregister
-@@ -2779,7 +3731,11 @@ static void ata_host_remove(struct ata_p
- * @ent: Probe information provided by low-level driver
- * @port_no: Port number associated with this ata_port
- *
-+ * Initialize a new ata_port structure, and its associated
-+ * scsi_host.
-+ *
- * LOCKING:
-+ * Inherited from caller.
- *
- */
-
-@@ -2794,7 +3750,7 @@ static void ata_host_init(struct ata_por
- host->max_channel = 1;
- host->unique_id = ata_unique_id++;
- host->max_cmd_len = 12;
-- scsi_set_device(host, &ent->pdev->dev);
-+ scsi_set_device(host, ent->dev);
- scsi_assign_lock(host, &host_set->lock);
-
- ap->flags = ATA_FLAG_PORT_DISABLED;
-@@ -2803,12 +3759,14 @@ static void ata_host_init(struct ata_por
- ap->ctl = ATA_DEVCTL_OBS;
- ap->host_set = host_set;
- ap->port_no = port_no;
-+ ap->hard_port_no =
-+ ent->legacy_mode ? ent->hard_port_no : port_no;
- ap->pio_mask = ent->pio_mask;
-+ ap->mwdma_mask = ent->mwdma_mask;
- ap->udma_mask = ent->udma_mask;
- ap->flags |= ent->host_flags;
- ap->ops = ent->port_ops;
- ap->cbl = ATA_CBL_NONE;
-- ap->device[0].flags = ATA_DFLAG_MASTER;
- ap->active_tag = ATA_TAG_POISON;
- ap->last_ctl = 0xFF;
-
-@@ -2832,9 +3790,13 @@ static void ata_host_init(struct ata_por
- * @host_set: Collections of ports to which we add
- * @port_no: Port number associated with this host
- *
-+ * Attach low-level ATA driver to system.
-+ *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- * RETURNS:
-+ * New ata_port on success, for NULL on error.
- *
- */
-
-@@ -2867,19 +3829,29 @@ err_out:
- }
-
- /**
-- * ata_device_add -
-- * @ent:
-+ * ata_device_add - Register hardware device with ATA and SCSI layers
-+ * @ent: Probe information describing hardware device to be registered
-+ *
-+ * This function processes the information provided in the probe
-+ * information struct @ent, allocates the necessary ATA and SCSI
-+ * host information structures, initializes them, and registers
-+ * everything with requisite kernel subsystems.
-+ *
-+ * This function requests irqs, probes the ATA bus, and probes
-+ * the SCSI bus.
- *
- * LOCKING:
-+ * PCI/etc. bus probe sem.
- *
- * RETURNS:
-+ * Number of ports registered. Zero on error (no ports registered).
- *
- */
-
- int ata_device_add(struct ata_probe_ent *ent)
- {
- unsigned int count = 0, i;
-- struct pci_dev *pdev = ent->pdev;
-+ struct device *dev = ent->dev;
- struct ata_host_set *host_set;
-
- DPRINTK("ENTER\n");
-@@ -2891,7 +3863,7 @@ int ata_device_add(struct ata_probe_ent
- memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
- spin_lock_init(&host_set->lock);
-
-- host_set->pdev = pdev;
-+ host_set->dev = dev;
- host_set->n_ports = ent->n_ports;
- host_set->irq = ent->irq;
- host_set->mmio_base = ent->mmio_base;
-@@ -2901,19 +3873,23 @@ int ata_device_add(struct ata_probe_ent
- /* register each port bound to this device */
- for (i = 0; i < ent->n_ports; i++) {
- struct ata_port *ap;
-+ unsigned long xfer_mode_mask;
-
- ap = ata_host_add(ent, host_set, i);
- if (!ap)
- goto err_out;
-
- host_set->ports[i] = ap;
-+ xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
-+ (ap->mwdma_mask << ATA_SHIFT_MWDMA) |
-+ (ap->pio_mask << ATA_SHIFT_PIO);
-
- /* print per-port info to dmesg */
- printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX "
- "bmdma 0x%lX irq %lu\n",
- ap->id,
- ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
-- ata_udma_string(ent->udma_mask),
-+ ata_mode_string(xfer_mode_mask),
- ap->ioaddr.cmd_addr,
- ap->ioaddr.ctl_addr,
- ap->ioaddr.bmdma_addr,
-@@ -2955,7 +3931,7 @@ int ata_device_add(struct ata_probe_ent
- */
- }
-
-- rc = scsi_add_host(ap->host, &pdev->dev);
-+ rc = scsi_add_host(ap->host, dev);
- if (rc) {
- printk(KERN_ERR "ata%u: scsi_add_host failed\n",
- ap->id);
-@@ -2975,7 +3951,7 @@ int ata_device_add(struct ata_probe_ent
- scsi_scan_host(ap->host);
- }
-
-- pci_set_drvdata(pdev, host_set);
-+ dev_set_drvdata(dev, host_set);
-
- VPRINTK("EXIT, returning %u\n", ent->n_ports);
- return ent->n_ports; /* success */
-@@ -3020,7 +3996,15 @@ int ata_scsi_release(struct Scsi_Host *h
- /**
- * ata_std_ports - initialize ioaddr with standard port offsets.
- * @ioaddr: IO address structure to be initialized
-+ *
-+ * Utility function which initializes data_addr, error_addr,
-+ * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
-+ * device_addr, status_addr, and command_addr to standard offsets
-+ * relative to cmd_addr.
-+ *
-+ * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
- */
-+
- void ata_std_ports(struct ata_ioports *ioaddr)
- {
- ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
-@@ -3035,16 +4019,141 @@ void ata_std_ports(struct ata_ioports *i
- ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
- }
-
-+static struct ata_probe_ent *
-+ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
-+{
-+ struct ata_probe_ent *probe_ent;
-+
-+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ if (!probe_ent) {
-+ printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
-+ kobject_name(&(dev->kobj)));
-+ return NULL;
-+ }
-+
-+ memset(probe_ent, 0, sizeof(*probe_ent));
-+
-+ INIT_LIST_HEAD(&probe_ent->node);
-+ probe_ent->dev = dev;
-+
-+ probe_ent->sht = port->sht;
-+ probe_ent->host_flags = port->host_flags;
-+ probe_ent->pio_mask = port->pio_mask;
-+ probe_ent->mwdma_mask = port->mwdma_mask;
-+ probe_ent->udma_mask = port->udma_mask;
-+ probe_ent->port_ops = port->port_ops;
-+
-+ return probe_ent;
-+}
-+
-+
-+
-+/**
-+ * ata_pci_init_native_mode - Initialize native-mode driver
-+ * @pdev: pci device to be initialized
-+ * @port: array[2] of pointers to port info structures.
-+ *
-+ * Utility function which allocates and initializes an
-+ * ata_probe_ent structure for a standard dual-port
-+ * PIO-based IDE controller. The returned ata_probe_ent
-+ * structure can be passed to ata_device_add(). The returned
-+ * ata_probe_ent structure should then be freed with kfree().
-+ */
-+
-+#ifdef CONFIG_PCI
-+struct ata_probe_ent *
-+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
-+{
-+ struct ata_probe_ent *probe_ent =
-+ ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
-+ if (!probe_ent)
-+ return NULL;
-+
-+ probe_ent->n_ports = 2;
-+ probe_ent->irq = pdev->irq;
-+ probe_ent->irq_flags = SA_SHIRQ;
-+
-+ probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
-+ probe_ent->port[0].altstatus_addr =
-+ probe_ent->port[0].ctl_addr =
-+ pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
-+ probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-+
-+ probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
-+ probe_ent->port[1].altstatus_addr =
-+ probe_ent->port[1].ctl_addr =
-+ pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-+ probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
-+
-+ ata_std_ports(&probe_ent->port[0]);
-+ ata_std_ports(&probe_ent->port[1]);
-+
-+ return probe_ent;
-+}
-+
-+static struct ata_probe_ent *
-+ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
-+ struct ata_probe_ent **ppe2)
-+{
-+ struct ata_probe_ent *probe_ent, *probe_ent2;
-+
-+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
-+ if (!probe_ent)
-+ return NULL;
-+ probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
-+ if (!probe_ent2) {
-+ kfree(probe_ent);
-+ return NULL;
-+ }
-+
-+ probe_ent->n_ports = 1;
-+ probe_ent->irq = 14;
-+
-+ probe_ent->hard_port_no = 0;
-+ probe_ent->legacy_mode = 1;
-+
-+ probe_ent2->n_ports = 1;
-+ probe_ent2->irq = 15;
-+
-+ probe_ent2->hard_port_no = 1;
-+ probe_ent2->legacy_mode = 1;
-+
-+ probe_ent->port[0].cmd_addr = 0x1f0;
-+ probe_ent->port[0].altstatus_addr =
-+ probe_ent->port[0].ctl_addr = 0x3f6;
-+ probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-+
-+ probe_ent2->port[0].cmd_addr = 0x170;
-+ probe_ent2->port[0].altstatus_addr =
-+ probe_ent2->port[0].ctl_addr = 0x376;
-+ probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
-+
-+ ata_std_ports(&probe_ent->port[0]);
-+ ata_std_ports(&probe_ent2->port[0]);
-+
-+ *ppe2 = probe_ent2;
-+ return probe_ent;
-+}
-+
- /**
- * ata_pci_init_one - Initialize/register PCI IDE host controller
- * @pdev: Controller to be initialized
- * @port_info: Information from low-level host driver
- * @n_ports: Number of ports attached to host controller
- *
-+ * This is a helper function which can be called from a driver's
-+ * xxx_init_one() probe function if the hardware uses traditional
-+ * IDE taskfile registers.
-+ *
-+ * This function calls pci_enable_device(), reserves its register
-+ * regions, sets the dma mask, enables bus master mode, and calls
-+ * ata_device_add()
-+ *
- * LOCKING:
- * Inherited from PCI layer (may sleep).
- *
- * RETURNS:
-+ * Zero on success, negative on errno-based value on error.
- *
- */
-
-@@ -3052,20 +4161,22 @@ int ata_pci_init_one (struct pci_dev *pd
- unsigned int n_ports)
- {
- struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
-- struct ata_port_info *port0, *port1;
-+ struct ata_port_info *port[2];
- u8 tmp8, mask;
- unsigned int legacy_mode = 0;
-+ int disable_dev_on_err = 1;
- int rc;
-
- DPRINTK("ENTER\n");
-
-- port0 = port_info[0];
-+ port[0] = port_info[0];
- if (n_ports > 1)
-- port1 = port_info[1];
-+ port[1] = port_info[1];
- else
-- port1 = port0;
-+ port[1] = port[0];
-
-- if ((port0->host_flags & ATA_FLAG_NO_LEGACY) == 0) {
-+ if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
-+ && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- /* TODO: support transitioning to native mode? */
- pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
- mask = (1 << 2) | (1 << 0);
-@@ -3084,8 +4195,10 @@ int ata_pci_init_one (struct pci_dev *pd
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ disable_dev_on_err = 0;
- goto err_out;
-+ }
-
- if (legacy_mode) {
- if (!request_region(0x1f0, 8, "libata")) {
-@@ -3095,8 +4208,10 @@ int ata_pci_init_one (struct pci_dev *pd
- conflict = ____request_resource(&ioport_resource, &res);
- if (!strcmp(conflict->name, "libata"))
- legacy_mode |= (1 << 0);
-- else
-+ else {
-+ disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
-+ }
- } else
- legacy_mode |= (1 << 0);
-
-@@ -3107,8 +4222,10 @@ int ata_pci_init_one (struct pci_dev *pd
- conflict = ____request_resource(&ioport_resource, &res);
- if (!strcmp(conflict->name, "libata"))
- legacy_mode |= (1 << 1);
-- else
-+ else {
-+ disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
-+ }
- } else
- legacy_mode |= (1 << 1);
- }
-@@ -3126,75 +4243,15 @@ int ata_pci_init_one (struct pci_dev *pd
- if (rc)
- goto err_out_regions;
-
-- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ if (legacy_mode) {
-+ probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
-+ } else
-+ probe_ent = ata_pci_init_native_mode(pdev, port);
- if (!probe_ent) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
-
-- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-- INIT_LIST_HEAD(&probe_ent->node);
--
-- if (legacy_mode) {
-- probe_ent2 = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-- if (!probe_ent2) {
-- rc = -ENOMEM;
-- goto err_out_free_ent;
-- }
--
-- memset(probe_ent2, 0, sizeof(*probe_ent));
-- probe_ent2->pdev = pdev;
-- INIT_LIST_HEAD(&probe_ent2->node);
-- }
--
-- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-- probe_ent->sht = port0->sht;
-- probe_ent->host_flags = port0->host_flags;
-- probe_ent->pio_mask = port0->pio_mask;
-- probe_ent->udma_mask = port0->udma_mask;
-- probe_ent->port_ops = port0->port_ops;
--
-- if (legacy_mode) {
-- probe_ent->port[0].cmd_addr = 0x1f0;
-- probe_ent->port[0].altstatus_addr =
-- probe_ent->port[0].ctl_addr = 0x3f6;
-- probe_ent->n_ports = 1;
-- probe_ent->irq = 14;
-- ata_std_ports(&probe_ent->port[0]);
--
-- probe_ent2->port[0].cmd_addr = 0x170;
-- probe_ent2->port[0].altstatus_addr =
-- probe_ent2->port[0].ctl_addr = 0x376;
-- probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
-- probe_ent2->n_ports = 1;
-- probe_ent2->irq = 15;
-- ata_std_ports(&probe_ent2->port[0]);
--
-- probe_ent2->sht = port1->sht;
-- probe_ent2->host_flags = port1->host_flags;
-- probe_ent2->pio_mask = port1->pio_mask;
-- probe_ent2->udma_mask = port1->udma_mask;
-- probe_ent2->port_ops = port1->port_ops;
-- } else {
-- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
-- ata_std_ports(&probe_ent->port[0]);
-- probe_ent->port[0].altstatus_addr =
-- probe_ent->port[0].ctl_addr =
-- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
--
-- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
-- ata_std_ports(&probe_ent->port[1]);
-- probe_ent->port[1].altstatus_addr =
-- probe_ent->port[1].ctl_addr =
-- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-- probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
--
-- probe_ent->n_ports = 2;
-- probe_ent->irq = pdev->irq;
-- probe_ent->irq_flags = SA_SHIRQ;
-- }
--
- pci_set_master(pdev);
-
- /* FIXME: check ata_device_add return */
-@@ -3203,17 +4260,14 @@ int ata_pci_init_one (struct pci_dev *pd
- ata_device_add(probe_ent);
- if (legacy_mode & (1 << 1))
- ata_device_add(probe_ent2);
-- kfree(probe_ent2);
-- } else {
-+ } else
- ata_device_add(probe_ent);
-- assert(probe_ent2 == NULL);
-- }
-+
- kfree(probe_ent);
-+ kfree(probe_ent2);
-
- return 0;
-
--err_out_free_ent:
-- kfree(probe_ent);
- err_out_regions:
- if (legacy_mode & (1 << 0))
- release_region(0x1f0, 8);
-@@ -3221,7 +4275,8 @@ err_out_regions:
- release_region(0x170, 8);
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (disable_dev_on_err)
-+ pci_disable_device(pdev);
- return rc;
- }
-
-@@ -3241,7 +4296,8 @@ err_out:
-
- void ata_pci_remove_one (struct pci_dev *pdev)
- {
-- struct ata_host_set *host_set = pci_get_drvdata(pdev);
-+ struct device *dev = pci_dev_to_dev(pdev);
-+ struct ata_host_set *host_set = dev_get_drvdata(dev);
- struct ata_port *ap;
- unsigned int i;
-
-@@ -3252,37 +4308,32 @@ void ata_pci_remove_one (struct pci_dev
- }
-
- free_irq(host_set->irq, host_set);
-- if (host_set->ops->host_stop)
-- host_set->ops->host_stop(host_set);
-- if (host_set->mmio_base)
-- iounmap(host_set->mmio_base);
-
- for (i = 0; i < host_set->n_ports; i++) {
- ap = host_set->ports[i];
-
- ata_scsi_release(ap->host);
-- scsi_host_put(ap->host);
-- }
--
-- pci_release_regions(pdev);
--
-- for (i = 0; i < host_set->n_ports; i++) {
-- struct ata_ioports *ioaddr;
--
-- ap = host_set->ports[i];
-- ioaddr = &ap->ioaddr;
-
- if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
-+ struct ata_ioports *ioaddr = &ap->ioaddr;
-+
- if (ioaddr->cmd_addr == 0x1f0)
- release_region(0x1f0, 8);
- else if (ioaddr->cmd_addr == 0x170)
- release_region(0x170, 8);
- }
-+
-+ scsi_host_put(ap->host);
- }
-
-+ if (host_set->ops->host_stop)
-+ host_set->ops->host_stop(host_set);
-+
- kfree(host_set);
-+
-+ pci_release_regions(pdev);
- pci_disable_device(pdev);
-- pci_set_drvdata(pdev, NULL);
-+ dev_set_drvdata(dev, NULL);
- }
-
- /* move to PCI subsystem */
-@@ -3318,17 +4369,9 @@ int pci_test_config_bits(struct pci_dev
-
- return (tmp == bits->val) ? 1 : 0;
- }
-+#endif /* CONFIG_PCI */
-
-
--/**
-- * ata_init -
-- *
-- * LOCKING:
-- *
-- * RETURNS:
-- *
-- */
--
- static int __init ata_init(void)
- {
- ata_wq = create_workqueue("ata");
-@@ -3354,7 +4397,6 @@ module_exit(ata_exit);
- * Do not depend on ABI/API stability.
- */
-
--EXPORT_SYMBOL_GPL(pci_test_config_bits);
- EXPORT_SYMBOL_GPL(ata_std_bios_param);
- EXPORT_SYMBOL_GPL(ata_std_ports);
- EXPORT_SYMBOL_GPL(ata_device_add);
-@@ -3363,34 +4405,48 @@ EXPORT_SYMBOL_GPL(ata_sg_init_one);
- EXPORT_SYMBOL_GPL(ata_qc_complete);
- EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
- EXPORT_SYMBOL_GPL(ata_eng_timeout);
--EXPORT_SYMBOL_GPL(ata_tf_load_pio);
--EXPORT_SYMBOL_GPL(ata_tf_load_mmio);
--EXPORT_SYMBOL_GPL(ata_tf_read_pio);
--EXPORT_SYMBOL_GPL(ata_tf_read_mmio);
-+EXPORT_SYMBOL_GPL(ata_tf_load);
-+EXPORT_SYMBOL_GPL(ata_tf_read);
-+EXPORT_SYMBOL_GPL(ata_noop_dev_select);
-+EXPORT_SYMBOL_GPL(ata_std_dev_select);
- EXPORT_SYMBOL_GPL(ata_tf_to_fis);
- EXPORT_SYMBOL_GPL(ata_tf_from_fis);
--EXPORT_SYMBOL_GPL(ata_check_status_pio);
--EXPORT_SYMBOL_GPL(ata_check_status_mmio);
--EXPORT_SYMBOL_GPL(ata_exec_command_pio);
--EXPORT_SYMBOL_GPL(ata_exec_command_mmio);
-+EXPORT_SYMBOL_GPL(ata_check_status);
-+EXPORT_SYMBOL_GPL(ata_altstatus);
-+EXPORT_SYMBOL_GPL(ata_chk_err);
-+EXPORT_SYMBOL_GPL(ata_exec_command);
- EXPORT_SYMBOL_GPL(ata_port_start);
- EXPORT_SYMBOL_GPL(ata_port_stop);
-+EXPORT_SYMBOL_GPL(ata_host_stop);
- EXPORT_SYMBOL_GPL(ata_interrupt);
- EXPORT_SYMBOL_GPL(ata_qc_prep);
--EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
--EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
--EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
--EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
-+EXPORT_SYMBOL_GPL(ata_bmdma_setup);
-+EXPORT_SYMBOL_GPL(ata_bmdma_start);
- EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
-+EXPORT_SYMBOL_GPL(ata_bmdma_status);
-+EXPORT_SYMBOL_GPL(ata_bmdma_stop);
- EXPORT_SYMBOL_GPL(ata_port_probe);
- EXPORT_SYMBOL_GPL(sata_phy_reset);
-+EXPORT_SYMBOL_GPL(__sata_phy_reset);
- EXPORT_SYMBOL_GPL(ata_bus_reset);
- EXPORT_SYMBOL_GPL(ata_port_disable);
--EXPORT_SYMBOL_GPL(ata_pci_init_one);
--EXPORT_SYMBOL_GPL(ata_pci_remove_one);
-+EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
- EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
- EXPORT_SYMBOL_GPL(ata_scsi_error);
- EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
- EXPORT_SYMBOL_GPL(ata_scsi_release);
-+EXPORT_SYMBOL_GPL(ata_scsi_dump_sanity_check);
-+EXPORT_SYMBOL_GPL(ata_scsi_dump_quiesce);
-+EXPORT_SYMBOL_GPL(ata_scsi_dump_poll);
- EXPORT_SYMBOL_GPL(ata_host_intr);
-+EXPORT_SYMBOL_GPL(ata_dev_classify);
- EXPORT_SYMBOL_GPL(ata_dev_id_string);
-+EXPORT_SYMBOL_GPL(ata_dev_config);
-+EXPORT_SYMBOL_GPL(ata_scsi_simulate);
-+
-+#ifdef CONFIG_PCI
-+EXPORT_SYMBOL_GPL(pci_test_config_bits);
-+EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
-+EXPORT_SYMBOL_GPL(ata_pci_init_one);
-+EXPORT_SYMBOL_GPL(ata_pci_remove_one);
-+#endif /* CONFIG_PCI */
---- ./drivers/scsi/sata_sil.c.libata 2005-09-26 13:33:11.000000000 +0400
-+++ ./drivers/scsi/sata_sil.c 2005-10-26 14:55:17.005915488 +0400
-@@ -6,7 +6,7 @@
- * on emails.
- *
- * Copyright 2003 Red Hat, Inc.
-- * Copyright 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
-+ * Copyright 2003 Benjamin Herrenschmidt
- *
- * The contents of this file are subject to the Open
- * Software License version 1.1 that can be found at
-@@ -38,12 +38,21 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "sata_sil"
--#define DRV_VERSION "0.54"
-+#define DRV_VERSION "0.9"
-
- enum {
- sil_3112 = 0,
- sil_3114 = 1,
-
-+ SIL_FIFO_R0 = 0x40,
-+ SIL_FIFO_W0 = 0x41,
-+ SIL_FIFO_R1 = 0x44,
-+ SIL_FIFO_W1 = 0x45,
-+ SIL_FIFO_R2 = 0x240,
-+ SIL_FIFO_W2 = 0x241,
-+ SIL_FIFO_R3 = 0x244,
-+ SIL_FIFO_W3 = 0x245,
-+
- SIL_SYSCFG = 0x48,
- SIL_MASK_IDE0_INT = (1 << 22),
- SIL_MASK_IDE1_INT = (1 << 23),
-@@ -71,12 +80,15 @@ static struct pci_device_id sil_pci_tbl[
- { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
- { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
- { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
-+ { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-+ { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-+ { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
- { } /* terminate list */
- };
-
-
- /* TODO firmware versions should be added - eric */
--struct sil_drivelist {
-+static const struct sil_drivelist {
- const char * product;
- unsigned int quirk;
- } sil_blacklist [] = {
-@@ -84,9 +96,12 @@ struct sil_drivelist {
- { "ST330013AS", SIL_QUIRK_MOD15WRITE },
- { "ST340017AS", SIL_QUIRK_MOD15WRITE },
- { "ST360015AS", SIL_QUIRK_MOD15WRITE },
-+ { "ST380013AS", SIL_QUIRK_MOD15WRITE },
- { "ST380023AS", SIL_QUIRK_MOD15WRITE },
- { "ST3120023AS", SIL_QUIRK_MOD15WRITE },
- { "ST3160023AS", SIL_QUIRK_MOD15WRITE },
-+ { "ST3120026AS", SIL_QUIRK_MOD15WRITE },
-+ { "ST3200822AS", SIL_QUIRK_MOD15WRITE },
- { "ST340014ASL", SIL_QUIRK_MOD15WRITE },
- { "ST360014ASL", SIL_QUIRK_MOD15WRITE },
- { "ST380011ASL", SIL_QUIRK_MOD15WRITE },
-@@ -106,6 +121,7 @@ static struct pci_driver sil_pci_driver
- static Scsi_Host_Template sil_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -124,14 +140,17 @@ static Scsi_Host_Template sil_sht = {
- static struct ata_port_operations sil_ops = {
- .port_disable = ata_port_disable,
- .dev_config = sil_dev_config,
-- .tf_load = ata_tf_load_mmio,
-- .tf_read = ata_tf_read_mmio,
-- .check_status = ata_check_status_mmio,
-- .exec_command = ata_exec_command_mmio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = sata_phy_reset,
- .post_set_mode = sil_post_set_mode,
-- .bmdma_setup = ata_bmdma_setup_mmio,
-- .bmdma_start = ata_bmdma_start_mmio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
-@@ -141,6 +160,7 @@ static struct ata_port_operations sil_op
- .scr_write = sil_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
- };
-
- static struct ata_port_info sil_port_info[] = {
-@@ -149,7 +169,8 @@ static struct ata_port_info sil_port_inf
- .sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SRST | ATA_FLAG_MMIO,
-- .pio_mask = 0x03, /* pio3-4 */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
- .port_ops = &sil_ops,
- }, /* sil_3114 */
-@@ -157,7 +178,8 @@ static struct ata_port_info sil_port_inf
- .sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SRST | ATA_FLAG_MMIO,
-- .pio_mask = 0x03, /* pio3-4 */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
- .port_ops = &sil_ops,
- },
-@@ -185,6 +207,14 @@ MODULE_AUTHOR("Jeff Garzik");
- MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-+
-+static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
-+{
-+ u8 cache_line = 0;
-+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line);
-+ return cache_line;
-+}
-
- static void sil_post_set_mode (struct ata_port *ap)
- {
-@@ -283,7 +313,7 @@ static void sil_dev_config(struct ata_po
- const char *s;
- unsigned int len;
-
-- ata_dev_id_string(dev, model_num, ATA_ID_PROD_OFS,
-+ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
-@@ -326,7 +356,9 @@ static int sil_init_one (struct pci_dev
- void *mmio_base;
- int rc;
- unsigned int i;
-+ int pci_dev_busy = 0;
- u32 tmp, irq_mask;
-+ u8 cls;
-
- if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
-@@ -340,8 +372,10 @@ static int sil_init_one (struct pci_dev
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -358,11 +392,12 @@ static int sil_init_one (struct pci_dev
-
- memset(probe_ent, 0, sizeof(*probe_ent));
- INIT_LIST_HEAD(&probe_ent->node);
-- probe_ent->pdev = pdev;
-+ probe_ent->dev = pci_dev_to_dev(pdev);
- probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
- probe_ent->sht = sil_port_info[ent->driver_data].sht;
- probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
- probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
-+ probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
- probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = SA_SHIRQ;
-@@ -388,6 +423,25 @@ static int sil_init_one (struct pci_dev
- ata_std_ports(&probe_ent->port[i]);
- }
-
-+ /* Initialize FIFO PCI bus arbitration */
-+ cls = sil_get_device_cache_line(pdev);
-+ if (cls) {
-+ cls >>= 3;
-+ cls++; /* cls = (line_size/8)+1 */
-+ writeb(cls, mmio_base + SIL_FIFO_R0);
-+ writeb(cls, mmio_base + SIL_FIFO_W0);
-+ writeb(cls, mmio_base + SIL_FIFO_R1);
-+ writeb(cls, mmio_base + SIL_FIFO_W1);
-+ if (ent->driver_data == sil_3114) {
-+ writeb(cls, mmio_base + SIL_FIFO_R2);
-+ writeb(cls, mmio_base + SIL_FIFO_W2);
-+ writeb(cls, mmio_base + SIL_FIFO_R3);
-+ writeb(cls, mmio_base + SIL_FIFO_W3);
-+ }
-+ } else
-+ printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n",
-+ pci_name(pdev));
-+
- if (ent->driver_data == sil_3114) {
- irq_mask = SIL_MASK_4PORT;
-
-@@ -427,7 +481,8 @@ err_out_free_ent:
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
---- ./drivers/scsi/sata_nv.c.libata 2005-09-26 13:33:13.000000000 +0400
-+++ ./drivers/scsi/sata_nv.c 2005-10-26 14:55:16.992917464 +0400
-@@ -20,6 +20,14 @@
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under either the OSL or the GPL.
- *
-+ * 0.06
-+ * - Added generic SATA support by using a pci_device_id that filters on
-+ * the IDE storage class code.
-+ *
-+ * 0.03
-+ * - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
-+ * mmio_base, which is only set for the CK804/MCP04 case.
-+ *
- * 0.02
- * - Added support for CK804 SATA controller.
- *
-@@ -40,13 +48,12 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "sata_nv"
--#define DRV_VERSION "0.02"
-+#define DRV_VERSION "0.6"
-
- #define NV_PORTS 2
- #define NV_PIO_MASK 0x1f
-+#define NV_MWDMA_MASK 0x07
- #define NV_UDMA_MASK 0x7f
--#define NV_PORT0_BMDMA_REG_OFFSET 0x00
--#define NV_PORT1_BMDMA_REG_OFFSET 0x08
- #define NV_PORT0_SCR_REG_OFFSET 0x00
- #define NV_PORT1_SCR_REG_OFFSET 0x40
-
-@@ -92,7 +99,8 @@
- #define NV_MCP_SATA_CFG_20_SATA_SPACE_EN 0x04
-
- static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
--irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-+static irqreturn_t nv_interrupt (int irq, void *dev_instance,
-+ struct pt_regs *regs);
- static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
- static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
- static void nv_host_stop (struct ata_host_set *host_set);
-@@ -105,6 +113,7 @@ static void nv_check_hotplug_ck804(struc
-
- enum nv_host_type
- {
-+ GENERIC,
- NFORCE2,
- NFORCE3,
- CK804
-@@ -125,6 +134,9 @@ static struct pci_device_id nv_pci_tbl[]
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-+ { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
-+ PCI_ANY_ID, PCI_ANY_ID,
-+ PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
- { 0, } /* terminate list */
- };
-
-@@ -133,7 +145,6 @@ static struct pci_device_id nv_pci_tbl[]
- struct nv_host_desc
- {
- enum nv_host_type host_type;
-- unsigned long host_flags;
- void (*enable_hotplug)(struct ata_probe_ent *probe_ent);
- void (*disable_hotplug)(struct ata_host_set *host_set);
- void (*check_hotplug)(struct ata_host_set *host_set);
-@@ -141,21 +152,24 @@ struct nv_host_desc
- };
- static struct nv_host_desc nv_device_tbl[] = {
- {
-+ .host_type = GENERIC,
-+ .enable_hotplug = NULL,
-+ .disable_hotplug= NULL,
-+ .check_hotplug = NULL,
-+ },
-+ {
- .host_type = NFORCE2,
-- .host_flags = 0x00000000,
- .enable_hotplug = nv_enable_hotplug,
- .disable_hotplug= nv_disable_hotplug,
- .check_hotplug = nv_check_hotplug,
- },
- {
- .host_type = NFORCE3,
-- .host_flags = 0x00000000,
- .enable_hotplug = nv_enable_hotplug,
- .disable_hotplug= nv_disable_hotplug,
- .check_hotplug = nv_check_hotplug,
- },
- { .host_type = CK804,
-- .host_flags = NV_HOST_FLAGS_SCR_MMIO,
- .enable_hotplug = nv_enable_hotplug_ck804,
- .disable_hotplug= nv_disable_hotplug_ck804,
- .check_hotplug = nv_check_hotplug_ck804,
-@@ -165,6 +179,7 @@ static struct nv_host_desc nv_device_tbl
- struct nv_host
- {
- struct nv_host_desc *host_desc;
-+ unsigned long host_flags;
- };
-
- static struct pci_driver nv_pci_driver = {
-@@ -177,11 +192,12 @@ static struct pci_driver nv_pci_driver =
- static Scsi_Host_Template nv_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
-- .sg_tablesize = ATA_MAX_PRD,
-+ .sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
-@@ -194,13 +210,16 @@ static Scsi_Host_Template nv_sht = {
-
- static struct ata_port_operations nv_ops = {
- .port_disable = ata_port_disable,
-- .tf_load = ata_tf_load_pio,
-- .tf_read = ata_tf_read_pio,
-- .exec_command = ata_exec_command_pio,
-- .check_status = ata_check_status_pio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .exec_command = ata_exec_command,
-+ .check_status = ata_check_status,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = sata_phy_reset,
-- .bmdma_setup = ata_bmdma_setup_pio,
-- .bmdma_start = ata_bmdma_start_pio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
-@@ -213,12 +232,34 @@ static struct ata_port_operations nv_ops
- .host_stop = nv_host_stop,
- };
-
-+/* FIXME: The hardware provides the necessary SATA PHY controls
-+ * to support ATA_FLAG_SATA_RESET. However, it is currently
-+ * necessary to disable that flag, to solve misdetection problems.
-+ * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info.
-+ *
-+ * This problem really needs to be investigated further. But in the
-+ * meantime, we avoid ATA_FLAG_SATA_RESET to get people working.
-+ */
-+static struct ata_port_info nv_port_info = {
-+ .sht = &nv_sht,
-+ .host_flags = ATA_FLAG_SATA |
-+ /* ATA_FLAG_SATA_RESET | */
-+ ATA_FLAG_SRST |
-+ ATA_FLAG_NO_LEGACY,
-+ .pio_mask = NV_PIO_MASK,
-+ .mwdma_mask = NV_MWDMA_MASK,
-+ .udma_mask = NV_UDMA_MASK,
-+ .port_ops = &nv_ops,
-+};
-+
- MODULE_AUTHOR("NVIDIA");
- MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
--irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
-+static irqreturn_t nv_interrupt (int irq, void *dev_instance,
-+ struct pt_regs *regs)
- {
- struct ata_host_set *host_set = dev_instance;
- struct nv_host *host = host_set->private_data;
-@@ -258,8 +299,8 @@ static u32 nv_scr_read (struct ata_port
- if (sc_reg > SCR_CONTROL)
- return 0xffffffffU;
-
-- if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-- return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
-+ if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-+ return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
- else
- return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
- }
-@@ -272,8 +313,8 @@ static void nv_scr_write (struct ata_por
- if (sc_reg > SCR_CONTROL)
- return;
-
-- if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-- writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
-+ if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-+ writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
- else
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
- }
-@@ -287,25 +328,39 @@ static void nv_host_stop (struct ata_hos
- host->host_desc->disable_hotplug(host_set);
-
- kfree(host);
-+
-+ ata_host_stop(host_set);
- }
-
- static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
- {
- static int printed_version = 0;
- struct nv_host *host;
-- struct ata_probe_ent *probe_ent = NULL;
-+ struct ata_port_info *ppi;
-+ struct ata_probe_ent *probe_ent;
-+ int pci_dev_busy = 0;
- int rc;
-+ u32 bar;
-+
-+ // Make sure this is a SATA controller by counting the number of bars
-+ // (NVIDIA SATA controllers will always have six bars). Otherwise,
-+ // it's an IDE controller and we ignore it.
-+ for (bar=0; bar<6; bar++)
-+ if (pci_resource_start(pdev, bar) == 0)
-+ return -ENODEV;
-
- if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
-
- rc = pci_enable_device(pdev);
- if (rc)
-- return rc;
-+ goto err_out;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-- goto err_out;
-+ if (rc) {
-+ pci_dev_busy = 1;
-+ goto err_out_disable;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -314,62 +369,34 @@ static int nv_init_one (struct pci_dev *
- if (rc)
- goto err_out_regions;
-
-- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-- if (!probe_ent) {
-- rc = -ENOMEM;
-+ rc = -ENOMEM;
-+
-+ ppi = &nv_port_info;
-+ probe_ent = ata_pci_init_native_mode(pdev, &ppi);
-+ if (!probe_ent)
- goto err_out_regions;
-- }
-
- host = kmalloc(sizeof(struct nv_host), GFP_KERNEL);
-- if (!host) {
-- rc = -ENOMEM;
-+ if (!host)
- goto err_out_free_ent;
-- }
-
-+ memset(host, 0, sizeof(struct nv_host));
- host->host_desc = &nv_device_tbl[ent->driver_data];
-
-- memset(probe_ent, 0, sizeof(*probe_ent));
-- INIT_LIST_HEAD(&probe_ent->node);
--
-- probe_ent->pdev = pdev;
-- probe_ent->sht = &nv_sht;
-- probe_ent->host_flags = ATA_FLAG_SATA |
-- ATA_FLAG_SATA_RESET |
-- ATA_FLAG_SRST |
-- ATA_FLAG_NO_LEGACY;
--
-- probe_ent->port_ops = &nv_ops;
-- probe_ent->n_ports = NV_PORTS;
-- probe_ent->irq = pdev->irq;
-- probe_ent->irq_flags = SA_SHIRQ;
-- probe_ent->pio_mask = NV_PIO_MASK;
-- probe_ent->udma_mask = NV_UDMA_MASK;
--
-- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
-- ata_std_ports(&probe_ent->port[0]);
-- probe_ent->port[0].altstatus_addr =
-- probe_ent->port[0].ctl_addr =
-- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
-- probe_ent->port[0].bmdma_addr =
-- pci_resource_start(pdev, 4) | NV_PORT0_BMDMA_REG_OFFSET;
--
-- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
-- ata_std_ports(&probe_ent->port[1]);
-- probe_ent->port[1].altstatus_addr =
-- probe_ent->port[1].ctl_addr =
-- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-- probe_ent->port[1].bmdma_addr =
-- pci_resource_start(pdev, 4) | NV_PORT1_BMDMA_REG_OFFSET;
--
- probe_ent->private_data = host;
-
-- if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
-+ if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM)
-+ host->host_flags |= NV_HOST_FLAGS_SCR_MMIO;
-+
-+ if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
- unsigned long base;
-
- probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5),
- pci_resource_len(pdev, 5));
-- if (probe_ent->mmio_base == NULL)
-- goto err_out_free_ent;
-+ if (probe_ent->mmio_base == NULL) {
-+ rc = -EIO;
-+ goto err_out_free_host;
-+ }
-
- base = (unsigned long)probe_ent->mmio_base;
-
-@@ -387,26 +414,31 @@ static int nv_init_one (struct pci_dev *
-
- pci_set_master(pdev);
-
-+ rc = ata_device_add(probe_ent);
-+ if (rc != NV_PORTS)
-+ goto err_out_iounmap;
-+
- // Enable hotplug event interrupts.
- if (host->host_desc->enable_hotplug)
- host->host_desc->enable_hotplug(probe_ent);
-
-- rc = ata_device_add(probe_ent);
-- if (rc != NV_PORTS)
-- goto err_out_free_ent;
--
- kfree(probe_ent);
-
- return 0;
-
-+err_out_iounmap:
-+ if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-+ iounmap(probe_ent->mmio_base);
-+err_out_free_host:
-+ kfree(host);
- err_out_free_ent:
- kfree(probe_ent);
--
- err_out_regions:
- pci_release_regions(pdev);
--
-+err_out_disable:
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- err_out:
-- pci_disable_device(pdev);
- return rc;
- }
-
-@@ -415,33 +447,33 @@ static void nv_enable_hotplug(struct ata
- u8 intr_mask;
-
- outb(NV_INT_STATUS_HOTPLUG,
-- (unsigned long)probe_ent->mmio_base + NV_INT_STATUS);
-+ probe_ent->port[0].scr_addr + NV_INT_STATUS);
-
-- intr_mask = inb((unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
-+ intr_mask = inb(probe_ent->port[0].scr_addr + NV_INT_ENABLE);
- intr_mask |= NV_INT_ENABLE_HOTPLUG;
-
-- outb(intr_mask, (unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
-+ outb(intr_mask, probe_ent->port[0].scr_addr + NV_INT_ENABLE);
- }
-
- static void nv_disable_hotplug(struct ata_host_set *host_set)
- {
- u8 intr_mask;
-
-- intr_mask = inb((unsigned long)host_set->mmio_base + NV_INT_ENABLE);
-+ intr_mask = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
-
- intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
-
-- outb(intr_mask, (unsigned long)host_set->mmio_base + NV_INT_ENABLE);
-+ outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
- }
-
- static void nv_check_hotplug(struct ata_host_set *host_set)
- {
- u8 intr_status;
-
-- intr_status = inb((unsigned long)host_set->mmio_base + NV_INT_STATUS);
-+ intr_status = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
-
- // Clear interrupt status.
-- outb(0xff, (unsigned long)host_set->mmio_base + NV_INT_STATUS);
-+ outb(0xff, host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
-
- if (intr_status & NV_INT_STATUS_HOTPLUG) {
- if (intr_status & NV_INT_STATUS_PDEV_ADDED)
-@@ -464,12 +496,13 @@ static void nv_check_hotplug(struct ata_
-
- static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
- {
-+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- u8 intr_mask;
- u8 regval;
-
-- pci_read_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, &regval);
-+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
- regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
-- pci_write_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, regval);
-+ pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
-
- writeb(NV_INT_STATUS_HOTPLUG, probe_ent->mmio_base + NV_INT_STATUS_CK804);
-
-@@ -481,6 +514,7 @@ static void nv_enable_hotplug_ck804(stru
-
- static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
- {
-+ struct pci_dev *pdev = to_pci_dev(host_set->dev);
- u8 intr_mask;
- u8 regval;
-
-@@ -490,9 +524,9 @@ static void nv_disable_hotplug_ck804(str
-
- writeb(intr_mask, host_set->mmio_base + NV_INT_ENABLE_CK804);
-
-- pci_read_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, &regval);
-+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
- regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
-- pci_write_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, regval);
-+ pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
- }
-
- static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
---- ./drivers/scsi/sata_via.c.libata 2005-09-26 13:33:12.000000000 +0400
-+++ ./drivers/scsi/sata_via.c 2005-10-26 14:55:17.000916248 +0400
-@@ -24,6 +24,11 @@
- If you do not delete the provisions above, a recipient may use your
- version of this file under either the OSL or the GPL.
-
-+ ----------------------------------------------------------------------
-+
-+ To-do list:
-+ * VT6421 PATA support
-+
- */
-
- #include <linux/kernel.h>
-@@ -38,11 +43,14 @@
- #include <asm/io.h>
-
- #define DRV_NAME "sata_via"
--#define DRV_VERSION "0.20"
-+#define DRV_VERSION "1.1"
-
--enum {
-- via_sata = 0,
-+enum board_ids_enum {
-+ vt6420,
-+ vt6421,
-+};
-
-+enum {
- SATA_CHAN_ENAB = 0x40, /* SATA channel enable */
- SATA_INT_GATE = 0x41, /* SATA interrupt gating */
- SATA_NATIVE_MODE = 0x42, /* Native mode enable */
-@@ -50,10 +58,8 @@ enum {
-
- PORT0 = (1 << 1),
- PORT1 = (1 << 0),
--
-- ENAB_ALL = PORT0 | PORT1,
--
-- INT_GATE_ALL = PORT0 | PORT1,
-+ ALL_PORTS = PORT0 | PORT1,
-+ N_PORTS = 2,
-
- NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
-
-@@ -66,7 +72,8 @@ static u32 svia_scr_read (struct ata_por
- static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-
- static struct pci_device_id svia_pci_tbl[] = {
-- { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, via_sata },
-+ { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
-+ { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
-
- { } /* terminate list */
- };
-@@ -81,6 +88,7 @@ static struct pci_driver svia_pci_driver
- static Scsi_Host_Template svia_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -99,15 +107,19 @@ static Scsi_Host_Template svia_sht = {
- static struct ata_port_operations svia_sata_ops = {
- .port_disable = ata_port_disable,
-
-- .tf_load = ata_tf_load_pio,
-- .tf_read = ata_tf_read_pio,
-- .check_status = ata_check_status_pio,
-- .exec_command = ata_exec_command_pio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
-
- .phy_reset = sata_phy_reset,
-
-- .bmdma_setup = ata_bmdma_setup_pio,
-- .bmdma_start = ata_bmdma_start_pio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
-+
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
-@@ -121,12 +133,23 @@ static struct ata_port_operations svia_s
-
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
-+};
-+
-+static struct ata_port_info svia_port_info = {
-+ .sht = &svia_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | ATA_FLAG_NO_LEGACY,
-+ .pio_mask = 0x1f,
-+ .mwdma_mask = 0x07,
-+ .udma_mask = 0x7f,
-+ .port_ops = &svia_sata_ops,
- };
-
- MODULE_AUTHOR("Jeff Garzik");
- MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
- {
-@@ -146,17 +169,132 @@ static const unsigned int svia_bar_sizes
- 8, 4, 8, 4, 16, 256
- };
-
-+static const unsigned int vt6421_bar_sizes[] = {
-+ 16, 16, 16, 16, 32, 128
-+};
-+
- static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
- {
- return addr + (port * 128);
- }
-
-+static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
-+{
-+ return addr + (port * 64);
-+}
-+
-+static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
-+ struct pci_dev *pdev,
-+ unsigned int port)
-+{
-+ unsigned long reg_addr = pci_resource_start(pdev, port);
-+ unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8);
-+ unsigned long scr_addr;
-+
-+ probe_ent->port[port].cmd_addr = reg_addr;
-+ probe_ent->port[port].altstatus_addr =
-+ probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS;
-+ probe_ent->port[port].bmdma_addr = bmdma_addr;
-+
-+ scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
-+ probe_ent->port[port].scr_addr = scr_addr;
-+
-+ ata_std_ports(&probe_ent->port[port]);
-+}
-+
-+static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
-+{
-+ struct ata_probe_ent *probe_ent;
-+ struct ata_port_info *ppi = &svia_port_info;
-+
-+ probe_ent = ata_pci_init_native_mode(pdev, &ppi);
-+ if (!probe_ent)
-+ return NULL;
-+
-+ probe_ent->port[0].scr_addr =
-+ svia_scr_addr(pci_resource_start(pdev, 5), 0);
-+ probe_ent->port[1].scr_addr =
-+ svia_scr_addr(pci_resource_start(pdev, 5), 1);
-+
-+ return probe_ent;
-+}
-+
-+static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
-+{
-+ struct ata_probe_ent *probe_ent;
-+ unsigned int i;
-+
-+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ if (!probe_ent)
-+ return NULL;
-+
-+ memset(probe_ent, 0, sizeof(*probe_ent));
-+ probe_ent->dev = pci_dev_to_dev(pdev);
-+ INIT_LIST_HEAD(&probe_ent->node);
-+
-+ probe_ent->sht = &svia_sht;
-+ probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
-+ ATA_FLAG_NO_LEGACY;
-+ probe_ent->port_ops = &svia_sata_ops;
-+ probe_ent->n_ports = N_PORTS;
-+ probe_ent->irq = pdev->irq;
-+ probe_ent->irq_flags = SA_SHIRQ;
-+ probe_ent->pio_mask = 0x1f;
-+ probe_ent->mwdma_mask = 0x07;
-+ probe_ent->udma_mask = 0x7f;
-+
-+ for (i = 0; i < N_PORTS; i++)
-+ vt6421_init_addrs(probe_ent, pdev, i);
-+
-+ return probe_ent;
-+}
-+
-+static void svia_configure(struct pci_dev *pdev)
-+{
-+ u8 tmp8;
-+
-+ pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
-+ printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
-+ pci_name(pdev),
-+ (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
-+
-+ /* make sure SATA channels are enabled */
-+ pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
-+ if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
-+ printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
-+ pci_name(pdev), (int) tmp8);
-+ tmp8 |= ALL_PORTS;
-+ pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
-+ }
-+
-+ /* make sure interrupts for each channel sent to us */
-+ pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
-+ if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
-+ printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
-+ pci_name(pdev), (int) tmp8);
-+ tmp8 |= ALL_PORTS;
-+ pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
-+ }
-+
-+ /* make sure native mode is enabled */
-+ pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
-+ if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
-+ printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
-+ pci_name(pdev), (int) tmp8);
-+ tmp8 |= NATIVE_MODE_ALL;
-+ pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
-+ }
-+}
-+
- static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
- {
- static int printed_version;
- unsigned int i;
- int rc;
- struct ata_probe_ent *probe_ent;
-+ int board_id = (int) ent->driver_data;
-+ const int *bar_sizes;
-+ int pci_dev_busy = 0;
- u8 tmp8;
-
- if (!printed_version++)
-@@ -167,20 +305,28 @@ static int svia_init_one (struct pci_dev
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
-- pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
-- if (tmp8 & SATA_2DEV) {
-- printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
-- pci_name(pdev), (int) tmp8);
-- rc = -EIO;
-- goto err_out_regions;
-+ if (board_id == vt6420) {
-+ pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
-+ if (tmp8 & SATA_2DEV) {
-+ printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
-+ pci_name(pdev), (int) tmp8);
-+ rc = -EIO;
-+ goto err_out_regions;
-+ }
-+
-+ bar_sizes = &svia_bar_sizes[0];
-+ } else {
-+ bar_sizes = &vt6421_bar_sizes[0];
- }
-
- for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
- if ((pci_resource_start(pdev, i) == 0) ||
-- (pci_resource_len(pdev, i) < svia_bar_sizes[i])) {
-+ (pci_resource_len(pdev, i) < bar_sizes[i])) {
- printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
- pci_name(pdev), i,
- pci_resource_start(pdev, i),
-@@ -196,75 +342,19 @@ static int svia_init_one (struct pci_dev
- if (rc)
- goto err_out_regions;
-
-- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ if (board_id == vt6420)
-+ probe_ent = vt6420_init_probe_ent(pdev);
-+ else
-+ probe_ent = vt6421_init_probe_ent(pdev);
-+
- if (!probe_ent) {
- printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
- pci_name(pdev));
- rc = -ENOMEM;
- goto err_out_regions;
- }
-- memset(probe_ent, 0, sizeof(*probe_ent));
-- INIT_LIST_HEAD(&probe_ent->node);
-- probe_ent->pdev = pdev;
-- probe_ent->sht = &svia_sht;
-- probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
-- ATA_FLAG_NO_LEGACY;
-- probe_ent->port_ops = &svia_sata_ops;
-- probe_ent->n_ports = 2;
-- probe_ent->irq = pdev->irq;
-- probe_ent->irq_flags = SA_SHIRQ;
-- probe_ent->pio_mask = 0x1f;
-- probe_ent->udma_mask = 0x7f;
--
-- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
-- ata_std_ports(&probe_ent->port[0]);
-- probe_ent->port[0].altstatus_addr =
-- probe_ent->port[0].ctl_addr =
-- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
-- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-- probe_ent->port[0].scr_addr =
-- svia_scr_addr(pci_resource_start(pdev, 5), 0);
-
-- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
-- ata_std_ports(&probe_ent->port[1]);
-- probe_ent->port[1].altstatus_addr =
-- probe_ent->port[1].ctl_addr =
-- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-- probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
-- probe_ent->port[1].scr_addr =
-- svia_scr_addr(pci_resource_start(pdev, 5), 1);
--
-- pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
-- printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
-- pci_name(pdev),
-- (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
--
-- /* make sure SATA channels are enabled */
-- pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
-- if ((tmp8 & ENAB_ALL) != ENAB_ALL) {
-- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
-- pci_name(pdev), (int) tmp8);
-- tmp8 |= ENAB_ALL;
-- pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
-- }
--
-- /* make sure interrupts for each channel sent to us */
-- pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
-- if ((tmp8 & INT_GATE_ALL) != INT_GATE_ALL) {
-- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
-- pci_name(pdev), (int) tmp8);
-- tmp8 |= INT_GATE_ALL;
-- pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
-- }
--
-- /* make sure native mode is enabled */
-- pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
-- if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
-- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
-- pci_name(pdev), (int) tmp8);
-- tmp8 |= NATIVE_MODE_ALL;
-- pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
-- }
-+ svia_configure(pdev);
-
- pci_set_master(pdev);
-
-@@ -277,7 +367,8 @@ static int svia_init_one (struct pci_dev
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
---- ./drivers/scsi/sata_sis.c.libata 2005-09-26 13:33:14.000000000 +0400
-+++ ./drivers/scsi/sata_sis.c 2005-10-26 14:55:17.004915640 +0400
-@@ -38,7 +38,7 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "sata_sis"
--#define DRV_VERSION "0.10"
-+#define DRV_VERSION "0.5"
-
- enum {
- sis_180 = 0,
-@@ -76,6 +76,7 @@ static struct pci_driver sis_pci_driver
- static Scsi_Host_Template sis_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -93,13 +94,16 @@ static Scsi_Host_Template sis_sht = {
-
- static struct ata_port_operations sis_ops = {
- .port_disable = ata_port_disable,
-- .tf_load = ata_tf_load_pio,
-- .tf_read = ata_tf_read_pio,
-- .check_status = ata_check_status_pio,
-- .exec_command = ata_exec_command_pio,
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = sata_phy_reset,
-- .bmdma_setup = ata_bmdma_setup_pio,
-- .bmdma_start = ata_bmdma_start_pio,
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
-@@ -109,6 +113,17 @@ static struct ata_port_operations sis_op
- .scr_write = sis_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
-+};
-+
-+static struct ata_port_info sis_port_info = {
-+ .sht = &sis_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
-+ ATA_FLAG_NO_LEGACY,
-+ .pio_mask = 0x1f,
-+ .mwdma_mask = 0x7,
-+ .udma_mask = 0x7f,
-+ .port_ops = &sis_ops,
- };
-
-
-@@ -116,6 +131,7 @@ MODULE_AUTHOR("Uwe Koziolek");
- MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
- {
-@@ -128,22 +144,24 @@ static unsigned int get_scr_cfg_addr(uns
-
- static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
- {
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
- u32 val;
-
- if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
- return 0xffffffff;
-- pci_read_config_dword(ap->host_set->pdev, cfg_addr, &val);
-+ pci_read_config_dword(pdev, cfg_addr, &val);
- return val;
- }
-
- static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
- {
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
-
- if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
- return;
-- pci_write_config_dword(ap->host_set->pdev, cfg_addr, val);
-+ pci_write_config_dword(pdev, cfg_addr, val);
- }
-
- static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
-@@ -184,14 +202,18 @@ static int sis_init_one (struct pci_dev
- struct ata_probe_ent *probe_ent = NULL;
- int rc;
- u32 genctl;
-+ struct ata_port_info *ppi;
-+ int pci_dev_busy = 0;
-
- rc = pci_enable_device(pdev);
- if (rc)
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -200,20 +222,13 @@ static int sis_init_one (struct pci_dev
- if (rc)
- goto err_out_regions;
-
-- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ ppi = &sis_port_info;
-+ probe_ent = ata_pci_init_native_mode(pdev, &ppi);
- if (!probe_ent) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
-
-- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-- INIT_LIST_HEAD(&probe_ent->node);
--
-- probe_ent->sht = &sis_sht;
-- probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
-- ATA_FLAG_NO_LEGACY;
--
- /* check and see if the SCRs are in IO space or PCI cfg space */
- pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
- if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
-@@ -230,31 +245,12 @@ static int sis_init_one (struct pci_dev
- probe_ent->host_flags |= SIS_FLAG_CFGSCR;
- }
-
-- probe_ent->pio_mask = 0x03;
-- probe_ent->udma_mask = 0x7f;
-- probe_ent->port_ops = &sis_ops;
--
-- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
-- ata_std_ports(&probe_ent->port[0]);
-- probe_ent->port[0].ctl_addr =
-- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
-- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-- if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR))
-+ if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) {
- probe_ent->port[0].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR);
--
-- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
-- ata_std_ports(&probe_ent->port[1]);
-- probe_ent->port[1].ctl_addr =
-- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-- probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
-- if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR))
- probe_ent->port[1].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64;
--
-- probe_ent->n_ports = 2;
-- probe_ent->irq = pdev->irq;
-- probe_ent->irq_flags = SA_SHIRQ;
-+ }
-
- pci_set_master(pdev);
- pci_enable_intx(pdev);
-@@ -269,7 +265,8 @@ err_out_regions:
- pci_release_regions(pdev);
-
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
-
- }
-@@ -284,6 +281,6 @@ static void __exit sis_exit(void)
- pci_unregister_driver(&sis_pci_driver);
- }
-
--
- module_init(sis_init);
- module_exit(sis_exit);
-+
---- ./drivers/scsi/sata_sx4.c.libata 2005-09-26 13:33:10.000000000 +0400
-+++ ./drivers/scsi/sata_sx4.c 2005-10-26 14:55:17.002915944 +0400
-@@ -40,7 +40,7 @@
- #include "sata_promise.h"
-
- #define DRV_NAME "sata_sx4"
--#define DRV_VERSION "0.50"
-+#define DRV_VERSION "0.7"
-
-
- enum {
-@@ -146,8 +146,6 @@ struct pdc_host_priv {
-
-
- static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
--static void pdc20621_dma_setup(struct ata_queued_cmd *qc);
--static void pdc20621_dma_start(struct ata_queued_cmd *qc);
- static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
- static void pdc_eng_timeout(struct ata_port *ap);
- static void pdc_20621_phy_reset (struct ata_port *ap);
-@@ -157,8 +155,6 @@ static void pdc20621_qc_prep(struct ata_
- static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
- static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
- static void pdc20621_host_stop(struct ata_host_set *host_set);
--static inline void pdc_dma_complete (struct ata_port *ap,
-- struct ata_queued_cmd *qc, int have_err);
- static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
- static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
- static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
-@@ -172,11 +168,13 @@ static void pdc20621_get_from_dimm(struc
- static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
- void *psource, u32 offset, u32 size);
- static void pdc20621_irq_clear(struct ata_port *ap);
-+static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
-
-
- static Scsi_Host_Template pdc_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
-@@ -195,14 +193,13 @@ static Scsi_Host_Template pdc_sata_sht =
- static struct ata_port_operations pdc_20621_ops = {
- .port_disable = ata_port_disable,
- .tf_load = pdc_tf_load_mmio,
-- .tf_read = ata_tf_read_mmio,
-- .check_status = ata_check_status_mmio,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
-+ .dev_select = ata_std_dev_select,
- .phy_reset = pdc_20621_phy_reset,
-- .bmdma_setup = pdc20621_dma_setup,
-- .bmdma_start = pdc20621_dma_start,
- .qc_prep = pdc20621_qc_prep,
-- .qc_issue = ata_qc_issue_prot,
-+ .qc_issue = pdc20621_qc_issue_prot,
- .eng_timeout = pdc_eng_timeout,
- .irq_handler = pdc20621_interrupt,
- .irq_clear = pdc20621_irq_clear,
-@@ -217,7 +214,8 @@ static struct ata_port_info pdc_port_inf
- .sht = &pdc_sata_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SRST | ATA_FLAG_MMIO,
-- .pio_mask = 0x03, /* pio3-4 */
-+ .pio_mask = 0x1f, /* pio0-4 */
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &pdc_20621_ops,
- },
-@@ -246,11 +244,13 @@ static void pdc20621_host_stop(struct at
-
- iounmap(dimm_mmio);
- kfree(hpriv);
-+
-+ ata_host_stop(host_set);
- }
-
- static int pdc_port_start(struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
- struct pdc_port_priv *pp;
- int rc;
-
-@@ -265,7 +265,7 @@ static int pdc_port_start(struct ata_por
- }
- memset(pp, 0, sizeof(*pp));
-
-- pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
-+ pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
-@@ -285,11 +285,11 @@ err_out:
-
- static void pdc_port_stop(struct ata_port *ap)
- {
-- struct pci_dev *pdev = ap->host_set->pdev;
-+ struct device *dev = ap->host_set->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
-- pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
-+ dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
- }
-@@ -377,7 +377,10 @@ static inline unsigned int pdc20621_ata_
-
- /* dimm dma S/G, and next-pkt */
- dw = i >> 2;
-- buf32[dw] = cpu_to_le32(dimm_sg);
-+ if (tf->protocol == ATA_PROT_NODATA)
-+ buf32[dw] = 0;
-+ else
-+ buf32[dw] = cpu_to_le32(dimm_sg);
- buf32[dw + 1] = 0;
- i += 8;
-
-@@ -437,7 +440,7 @@ static inline void pdc20621_host_pkt(str
- buf32[dw + 3]);
- }
-
--static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
-+static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
- {
- struct scatterlist *sg = qc->sg;
- struct ata_port *ap = qc->ap;
-@@ -449,8 +452,7 @@ static void pdc20621_qc_prep(struct ata_
- unsigned int i, last, idx, total_len = 0, sgt_len;
- u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
-
-- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
-- return;
-+ assert(qc->flags & ATA_QCFLAG_DMAMAP);
-
- VPRINTK("ata%u: ENTER\n", ap->id);
-
-@@ -501,6 +503,56 @@ static void pdc20621_qc_prep(struct ata_
- VPRINTK("ata pkt buf ofs %u, prd size %u, mmio copied\n", i, sgt_len);
- }
-
-+static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ struct pdc_port_priv *pp = ap->private_data;
-+ void *mmio = ap->host_set->mmio_base;
-+ struct pdc_host_priv *hpriv = ap->host_set->private_data;
-+ void *dimm_mmio = hpriv->dimm_mmio;
-+ unsigned int portno = ap->port_no;
-+ unsigned int i;
-+
-+ VPRINTK("ata%u: ENTER\n", ap->id);
-+
-+ /* hard-code chip #0 */
-+ mmio += PDC_CHIP0_OFS;
-+
-+ i = pdc20621_ata_pkt(&qc->tf, qc->dev->devno, &pp->dimm_buf[0], portno);
-+
-+ if (qc->tf.flags & ATA_TFLAG_LBA48)
-+ i = pdc_prep_lba48(&qc->tf, &pp->dimm_buf[0], i);
-+ else
-+ i = pdc_prep_lba28(&qc->tf, &pp->dimm_buf[0], i);
-+
-+ pdc_pkt_footer(&qc->tf, &pp->dimm_buf[0], i);
-+
-+ /* copy three S/G tables and two packets to DIMM MMIO window */
-+ memcpy_toio(dimm_mmio + (portno * PDC_DIMM_WINDOW_STEP),
-+ &pp->dimm_buf, PDC_DIMM_HEADER_SZ);
-+
-+ /* force host FIFO dump */
-+ writel(0x00000001, mmio + PDC_20621_GENERAL_CTL);
-+
-+ readl(dimm_mmio); /* MMIO PCI posting flush */
-+
-+ VPRINTK("ata pkt buf ofs %u, mmio copied\n", i);
-+}
-+
-+static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
-+{
-+ switch (qc->tf.protocol) {
-+ case ATA_PROT_DMA:
-+ pdc20621_dma_prep(qc);
-+ break;
-+ case ATA_PROT_NODATA:
-+ pdc20621_nodata_prep(qc);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
- unsigned int seq,
- u32 pkt_ofs)
-@@ -576,13 +628,7 @@ static void pdc20621_dump_hdma(struct at
- static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { }
- #endif /* ATA_VERBOSE_DEBUG */
-
--static void pdc20621_dma_setup(struct ata_queued_cmd *qc)
--{
-- /* nothing for now. later, we will call standard
-- * code in libata-core for ATAPI here */
--}
--
--static void pdc20621_dma_start(struct ata_queued_cmd *qc)
-+static void pdc20621_packet_start(struct ata_queued_cmd *qc)
- {
- struct ata_port *ap = qc->ap;
- struct ata_host_set *host_set = ap->host_set;
-@@ -590,24 +636,21 @@ static void pdc20621_dma_start(struct at
- void *mmio = host_set->mmio_base;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 seq = (u8) (port_no + 1);
-- unsigned int doing_hdma = 0, port_ofs;
-+ unsigned int port_ofs;
-
- /* hard-code chip #0 */
- mmio += PDC_CHIP0_OFS;
-
- VPRINTK("ata%u: ENTER\n", ap->id);
-
-+ wmb(); /* flush PRD, pkt writes */
-+
- port_ofs = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * port_no);
-
- /* if writing, we (1) DMA to DIMM, then (2) do ATA command */
-- if (rw) {
-- doing_hdma = 1;
-+ if (rw && qc->tf.protocol == ATA_PROT_DMA) {
- seq += 4;
-- }
--
-- wmb(); /* flush PRD, pkt writes */
-
-- if (doing_hdma) {
- pdc20621_dump_hdma(qc);
- pdc20621_push_hdma(qc, seq, port_ofs + PDC_DIMM_HOST_PKT);
- VPRINTK("queued ofs 0x%x (%u), seq %u\n",
-@@ -628,6 +671,25 @@ static void pdc20621_dma_start(struct at
- }
- }
-
-+static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
-+{
-+ switch (qc->tf.protocol) {
-+ case ATA_PROT_DMA:
-+ case ATA_PROT_NODATA:
-+ pdc20621_packet_start(qc);
-+ return 0;
-+
-+ case ATA_PROT_ATAPI_DMA:
-+ BUG();
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return ata_qc_issue_prot(qc);
-+}
-+
- static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
- struct ata_queued_cmd *qc,
- unsigned int doing_hdma,
-@@ -648,7 +710,8 @@ static inline unsigned int pdc20621_host
- if (doing_hdma) {
- VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
- readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
-- pdc_dma_complete(ap, qc, 0);
-+ /* get drive status; clear intr; complete txn */
-+ ata_qc_complete(qc, ata_wait_idle(ap));
- pdc20621_pop_hdma(qc);
- }
-
-@@ -685,7 +748,8 @@ static inline unsigned int pdc20621_host
- else {
- VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
- readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
-- pdc_dma_complete(ap, qc, 0);
-+ /* get drive status; clear intr; complete txn */
-+ ata_qc_complete(qc, ata_wait_idle(ap));
- pdc20621_pop_hdma(qc);
- }
- handled = 1;
-@@ -779,16 +843,6 @@ static irqreturn_t pdc20621_interrupt (i
- return IRQ_RETVAL(handled);
- }
-
--static inline void pdc_dma_complete (struct ata_port *ap,
-- struct ata_queued_cmd *qc,
-- int have_err)
--{
-- u8 err_bit = have_err ? ATA_ERR : 0;
--
-- /* get drive status; clear intr; complete txn */
-- ata_qc_complete(qc, ata_wait_idle(ap) | err_bit);
--}
--
- static void pdc_eng_timeout(struct ata_port *ap)
- {
- u8 drv_stat;
-@@ -813,17 +867,9 @@ static void pdc_eng_timeout(struct ata_p
-
- switch (qc->tf.protocol) {
- case ATA_PROT_DMA:
-- printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
-- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
-- break;
--
- case ATA_PROT_NODATA:
-- drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
--
-- printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n",
-- ap->id, qc->tf.command, drv_stat);
--
-- ata_qc_complete(qc, drv_stat);
-+ printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-+ ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
- break;
-
- default:
-@@ -842,15 +888,17 @@ out:
-
- static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
-- if (tf->protocol != ATA_PROT_DMA)
-- ata_tf_load_mmio(ap, tf);
-+ WARN_ON (tf->protocol == ATA_PROT_DMA ||
-+ tf->protocol == ATA_PROT_NODATA);
-+ ata_tf_load(ap, tf);
- }
-
-
- static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
- {
-- if (tf->protocol != ATA_PROT_DMA)
-- ata_exec_command_mmio(ap, tf);
-+ WARN_ON (tf->protocol == ATA_PROT_DMA ||
-+ tf->protocol == ATA_PROT_NODATA);
-+ ata_exec_command(ap, tf);
- }
-
-
-@@ -1144,8 +1192,7 @@ static unsigned int pdc20621_prog_dimm_g
- error = 0;
- break;
- }
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout((i * 100) * HZ / 1000 + 1);
-+ msleep(i*100);
- }
- return error;
- }
-@@ -1178,8 +1225,7 @@ static unsigned int pdc20621_dimm_init(s
- readl(mmio + PDC_TIME_CONTROL);
-
- /* Wait 3 seconds */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(3 * HZ);
-+ msleep(3000);
-
- /*
- When timer is enabled, counter is decreased every internal
-@@ -1322,6 +1368,7 @@ static int pdc_sata_init_one (struct pci
- void *mmio_base, *dimm_mmio = NULL;
- struct pdc_host_priv *hpriv = NULL;
- unsigned int board_idx = (unsigned int) ent->driver_data;
-+ int pci_dev_busy = 0;
- int rc;
-
- if (!printed_version++)
-@@ -1336,8 +1383,10 @@ static int pdc_sata_init_one (struct pci
- return rc;
-
- rc = pci_request_regions(pdev, DRV_NAME);
-- if (rc)
-+ if (rc) {
-+ pci_dev_busy = 1;
- goto err_out;
-+ }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
-@@ -1353,7 +1402,7 @@ static int pdc_sata_init_one (struct pci
- }
-
- memset(probe_ent, 0, sizeof(*probe_ent));
-- probe_ent->pdev = pdev;
-+ probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- mmio_base = ioremap(pci_resource_start(pdev, 3),
-@@ -1384,6 +1433,7 @@ static int pdc_sata_init_one (struct pci
- probe_ent->sht = pdc_port_info[board_idx].sht;
- probe_ent->host_flags = pdc_port_info[board_idx].host_flags;
- probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
-+ probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
- probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
-
-@@ -1394,21 +1444,11 @@ static int pdc_sata_init_one (struct pci
- probe_ent->private_data = hpriv;
- base += PDC_CHIP0_OFS;
-
-+ probe_ent->n_ports = 4;
- pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
- pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
--
-- /* notice 4-port boards */
-- switch (board_idx) {
-- case board_20621:
-- probe_ent->n_ports = 4;
--
-- pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-- pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
-- break;
-- default:
-- BUG();
-- break;
-- }
-+ pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-+ pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
-
- pci_set_master(pdev);
-
-@@ -1436,7 +1476,8 @@ err_out_free_ent:
- err_out_regions:
- pci_release_regions(pdev);
- err_out:
-- pci_disable_device(pdev);
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
- return rc;
- }
-
-@@ -1457,6 +1498,7 @@ MODULE_AUTHOR("Jeff Garzik");
- MODULE_DESCRIPTION("Promise SATA low-level driver");
- MODULE_LICENSE("GPL");
- MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-
- module_init(pdc_sata_init);
- module_exit(pdc_sata_exit);
---- ./drivers/scsi/libata-scsi.c.libata 2005-09-26 13:33:13.000000000 +0400
-+++ ./drivers/scsi/libata-scsi.c 2005-10-26 14:55:16.996916856 +0400
-@@ -29,13 +29,11 @@
- #include "scsi.h"
- #include <scsi/scsi_host.h>
- #include <linux/libata.h>
-+#include <asm/uaccess.h>
-
- #include "libata.h"
-
- typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
--static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
-- struct scsi_cmnd *cmd,
-- void (*done)(struct scsi_cmnd *));
-
-
- /**
-@@ -67,6 +65,43 @@ int ata_std_bios_param(struct scsi_devic
- return 0;
- }
-
-+int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
-+{
-+ struct ata_port *ap;
-+ struct ata_device *dev;
-+ int val = -EINVAL, rc = -EINVAL;
-+
-+ ap = (struct ata_port *) &scsidev->host->hostdata[0];
-+ if (!ap)
-+ goto out;
-+
-+ dev = ata_scsi_find_dev(ap, scsidev);
-+ if (!dev) {
-+ rc = -ENODEV;
-+ goto out;
-+ }
-+
-+ switch (cmd) {
-+ case ATA_IOC_GET_IO32:
-+ val = 0;
-+ if (copy_to_user(arg, &val, 1))
-+ return -EFAULT;
-+ return 0;
-+
-+ case ATA_IOC_SET_IO32:
-+ val = (unsigned long) arg;
-+ if (val != 0)
-+ return -EINVAL;
-+ return 0;
-+
-+ default:
-+ rc = -ENOTTY;
-+ break;
-+ }
-+
-+out:
-+ return rc;
-+}
-
- /**
- * ata_scsi_qc_new - acquire new ata_queued_cmd reference
-@@ -119,35 +154,161 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
- /**
- * ata_to_sense_error - convert ATA error to SCSI error
- * @qc: Command that we are erroring out
-+ * @drv_stat: value contained in ATA status register
- *
-- * Converts an ATA error into a SCSI error.
-- *
-- * Right now, this routine is laughably primitive. We
-- * don't even examine what ATA told us, we just look at
-- * the command data direction, and return a fatal SCSI
-- * sense error based on that.
-+ * Converts an ATA error into a SCSI error. While we are at it
-+ * we decode and dump the ATA error for the user so that they
-+ * have some idea what really happened at the non make-believe
-+ * layer.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- */
-
--void ata_to_sense_error(struct ata_queued_cmd *qc)
-+void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
- {
- struct scsi_cmnd *cmd = qc->scsicmd;
-+ u8 err = 0;
-+ unsigned char *sb = cmd->sense_buffer;
-+ /* Based on the 3ware driver translation table */
-+ static unsigned char sense_table[][4] = {
-+ /* BBD|ECC|ID|MAR */
-+ {0xd1, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
-+ /* BBD|ECC|ID */
-+ {0xd0, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
-+ /* ECC|MC|MARK */
-+ {0x61, HARDWARE_ERROR, 0x00, 0x00}, // Device fault Hardware error
-+ /* ICRC|ABRT */ /* NB: ICRC & !ABRT is BBD */
-+ {0x84, ABORTED_COMMAND, 0x47, 0x00}, // Data CRC error SCSI parity error
-+ /* MC|ID|ABRT|TRK0|MARK */
-+ {0x37, NOT_READY, 0x04, 0x00}, // Unit offline Not ready
-+ /* MCR|MARK */
-+ {0x09, NOT_READY, 0x04, 0x00}, // Unrecovered disk error Not ready
-+ /* Bad address mark */
-+ {0x01, MEDIUM_ERROR, 0x13, 0x00}, // Address mark not found Address mark not found for data field
-+ /* TRK0 */
-+ {0x02, HARDWARE_ERROR, 0x00, 0x00}, // Track 0 not found Hardware error
-+ /* Abort & !ICRC */
-+ {0x04, ABORTED_COMMAND, 0x00, 0x00}, // Aborted command Aborted command
-+ /* Media change request */
-+ {0x08, NOT_READY, 0x04, 0x00}, // Media change request FIXME: faking offline
-+ /* SRV */
-+ {0x10, ABORTED_COMMAND, 0x14, 0x00}, // ID not found Recorded entity not found
-+ /* Media change */
-+ {0x08, NOT_READY, 0x04, 0x00}, // Media change FIXME: faking offline
-+ /* ECC */
-+ {0x40, MEDIUM_ERROR, 0x11, 0x04}, // Uncorrectable ECC error Unrecovered read error
-+ /* BBD - block marked bad */
-+ {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error
-+ {0xFF, 0xFF, 0xFF, 0xFF}, // END mark
-+ };
-+ static unsigned char stat_table[][4] = {
-+ /* Must be first because BUSY means no other bits valid */
-+ {0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now
-+ {0x20, HARDWARE_ERROR, 0x00, 0x00}, // Device fault
-+ {0x08, ABORTED_COMMAND, 0x47, 0x00}, // Timed out in xfer, fake parity for now
-+ {0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
-+ {0xFF, 0xFF, 0xFF, 0xFF}, // END mark
-+ };
-+ int i = 0;
-
- cmd->result = SAM_STAT_CHECK_CONDITION;
-
-- cmd->sense_buffer[0] = 0x70;
-- cmd->sense_buffer[2] = MEDIUM_ERROR;
-- cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */
-+ /*
-+ * Is this an error we can process/parse
-+ */
-+
-+ if(drv_stat & ATA_ERR)
-+ /* Read the err bits */
-+ err = ata_chk_err(qc->ap);
-+
-+ /* Display the ATA level error info */
-+
-+ printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
-+ if(drv_stat & 0x80)
-+ {
-+ printk("Busy ");
-+ err = 0; /* Data is not valid in this case */
-+ }
-+ else {
-+ if(drv_stat & 0x40) printk("DriveReady ");
-+ if(drv_stat & 0x20) printk("DeviceFault ");
-+ if(drv_stat & 0x10) printk("SeekComplete ");
-+ if(drv_stat & 0x08) printk("DataRequest ");
-+ if(drv_stat & 0x04) printk("CorrectedError ");
-+ if(drv_stat & 0x02) printk("Index ");
-+ if(drv_stat & 0x01) printk("Error ");
-+ }
-+ printk("}\n");
-+
-+ if(err)
-+ {
-+ printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
-+ if(err & 0x04) printk("DriveStatusError ");
-+ if(err & 0x80)
-+ {
-+ if(err & 0x04)
-+ printk("BadCRC ");
-+ else
-+ printk("Sector ");
-+ }
-+ if(err & 0x40) printk("UncorrectableError ");
-+ if(err & 0x10) printk("SectorIdNotFound ");
-+ if(err & 0x02) printk("TrackZeroNotFound ");
-+ if(err & 0x01) printk("AddrMarkNotFound ");
-+ printk("}\n");
-+
-+ /* Should we dump sector info here too ?? */
-+ }
-+
-
-+ /* Look for err */
-+ while(sense_table[i][0] != 0xFF)
-+ {
-+ /* Look for best matches first */
-+ if((sense_table[i][0] & err) == sense_table[i][0])
-+ {
-+ sb[0] = 0x70;
-+ sb[2] = sense_table[i][1];
-+ sb[7] = 0x0a;
-+ sb[12] = sense_table[i][2];
-+ sb[13] = sense_table[i][3];
-+ return;
-+ }
-+ i++;
-+ }
-+ /* No immediate match */
-+ if(err)
-+ printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
-+
-+ i = 0;
-+ /* Fall back to interpreting status bits */
-+ while(stat_table[i][0] != 0xFF)
-+ {
-+ if(stat_table[i][0] & drv_stat)
-+ {
-+ sb[0] = 0x70;
-+ sb[2] = stat_table[i][1];
-+ sb[7] = 0x0a;
-+ sb[12] = stat_table[i][2];
-+ sb[13] = stat_table[i][3];
-+ return;
-+ }
-+ i++;
-+ }
-+ /* No error ?? */
-+ printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
- /* additional-sense-code[-qualifier] */
-- if (cmd->sc_data_direction == SCSI_DATA_READ) {
-- cmd->sense_buffer[12] = 0x11; /* "unrecovered read error" */
-- cmd->sense_buffer[13] = 0x04;
-+
-+ sb[0] = 0x70;
-+ sb[2] = MEDIUM_ERROR;
-+ sb[7] = 0x0A;
-+ if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
-+ sb[12] = 0x11; /* "unrecovered read error" */
-+ sb[13] = 0x04;
- } else {
-- cmd->sense_buffer[12] = 0x0C; /* "write error - */
-- cmd->sense_buffer[13] = 0x02; /* auto-reallocation failed" */
-+ sb[12] = 0x0C; /* "write error - */
-+ sb[13] = 0x02; /* auto-reallocation failed" */
- }
- }
-
-@@ -184,7 +345,10 @@ int ata_scsi_slave_config(struct scsi_de
- */
- if ((dev->flags & ATA_DFLAG_LBA48) &&
- ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
-- sdev->host->max_sectors = 2048;
-+ /*
-+ * do not overwrite sdev->host->max_sectors, since
-+ * other drives on this host may not support LBA48
-+ */
- blk_queue_max_sectors(sdev->request_queue, 2048);
- }
- }
-@@ -214,11 +378,140 @@ int ata_scsi_error(struct Scsi_Host *hos
- ap = (struct ata_port *) &host->hostdata[0];
- ap->ops->eng_timeout(ap);
-
-+ /* TODO: this is per-command; when queueing is supported
-+ * this code will either change or move to a more
-+ * appropriate place
-+ */
-+ host->host_failed--;
-+
- DPRINTK("EXIT\n");
- return 0;
- }
-
- /**
-+ * 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.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ *
-+ * RETURNS:
-+ * Zero on success, non-zero on error.
-+ */
-+
-+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
-+{
-+ struct ata_taskfile *tf = &qc->tf;
-+
-+ tf->flags |= ATA_TFLAG_DEVICE;
-+ tf->protocol = ATA_PROT_NODATA;
-+
-+ if ((tf->flags & ATA_TFLAG_LBA48) &&
-+ (ata_id_has_flush_ext(qc->dev->id)))
-+ tf->command = ATA_CMD_FLUSH_EXT;
-+ else
-+ tf->command = ATA_CMD_FLUSH;
-+
-+ return 0;
-+}
-+
-+/**
-+ * 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.
-+ *
-+ * LOCKING:
-+ * spin_lock_irqsave(host_set lock)
-+ *
-+ * RETURNS:
-+ * Zero on success, non-zero on error.
-+ */
-+
-+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
-+{
-+ struct ata_taskfile *tf = &qc->tf;
-+ unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
-+ u64 dev_sectors = qc->dev->n_sectors;
-+ u64 sect = 0;
-+ u32 n_sect = 0;
-+
-+ tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-+ tf->protocol = ATA_PROT_NODATA;
-+ tf->device |= ATA_LBA;
-+
-+ if (scsicmd[0] == VERIFY) {
-+ sect |= ((u64)scsicmd[2]) << 24;
-+ sect |= ((u64)scsicmd[3]) << 16;
-+ sect |= ((u64)scsicmd[4]) << 8;
-+ sect |= ((u64)scsicmd[5]);
-+
-+ n_sect |= ((u32)scsicmd[7]) << 8;
-+ n_sect |= ((u32)scsicmd[8]);
-+ }
-+
-+ else if (scsicmd[0] == VERIFY_16) {
-+ sect |= ((u64)scsicmd[2]) << 56;
-+ sect |= ((u64)scsicmd[3]) << 48;
-+ sect |= ((u64)scsicmd[4]) << 40;
-+ sect |= ((u64)scsicmd[5]) << 32;
-+ sect |= ((u64)scsicmd[6]) << 24;
-+ sect |= ((u64)scsicmd[7]) << 16;
-+ sect |= ((u64)scsicmd[8]) << 8;
-+ sect |= ((u64)scsicmd[9]);
-+
-+ n_sect |= ((u32)scsicmd[10]) << 24;
-+ n_sect |= ((u32)scsicmd[11]) << 16;
-+ n_sect |= ((u32)scsicmd[12]) << 8;
-+ n_sect |= ((u32)scsicmd[13]);
-+ }
-+
-+ else
-+ return 1;
-+
-+ if (!n_sect)
-+ return 1;
-+ if (sect >= dev_sectors)
-+ return 1;
-+ if ((sect + n_sect) > dev_sectors)
-+ return 1;
-+ if (lba48) {
-+ if (n_sect > (64 * 1024))
-+ return 1;
-+ } else {
-+ if (n_sect > 256)
-+ return 1;
-+ }
-+
-+ if (lba48) {
-+ tf->command = ATA_CMD_VERIFY_EXT;
-+
-+ tf->hob_nsect = (n_sect >> 8) & 0xff;
-+
-+ tf->hob_lbah = (sect >> 40) & 0xff;
-+ tf->hob_lbam = (sect >> 32) & 0xff;
-+ tf->hob_lbal = (sect >> 24) & 0xff;
-+ } else {
-+ tf->command = ATA_CMD_VERIFY;
-+
-+ tf->device |= (sect >> 24) & 0xf;
-+ }
-+
-+ tf->nsect = n_sect & 0xff;
-+
-+ tf->lbah = (sect >> 16) & 0xff;
-+ tf->lbam = (sect >> 8) & 0xff;
-+ tf->lbal = sect & 0xff;
-+
-+ return 0;
-+}
-+
-+/**
- * ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
- * @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
-@@ -244,10 +537,6 @@ static unsigned int ata_scsi_rw_xlat(str
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
-
- tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-- tf->hob_nsect = 0;
-- tf->hob_lbal = 0;
-- tf->hob_lbam = 0;
-- tf->hob_lbah = 0;
- tf->protocol = qc->dev->xfer_protocol;
- tf->device |= ATA_LBA;
-
-@@ -317,7 +606,7 @@ static unsigned int ata_scsi_rw_xlat(str
- return 1;
-
- /* stores LBA27:24 in lower 4 bits of device reg */
-- tf->device |= scsicmd[2];
-+ tf->device |= scsicmd[6];
-
- qc->nsect = scsicmd[13];
- }
-@@ -339,14 +628,10 @@ static int ata_scsi_qc_complete(struct a
- {
- struct scsi_cmnd *cmd = qc->scsicmd;
-
-- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
-- if (is_atapi_taskfile(&qc->tf))
-- cmd->result = SAM_STAT_CHECK_CONDITION;
-- else
-- ata_to_sense_error(qc);
-- } else {
-+ if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
-+ ata_to_sense_error(qc, drv_stat);
-+ else
- cmd->result = SAM_STAT_GOOD;
-- }
-
- qc->scsidone(cmd);
-
-@@ -387,8 +672,8 @@ static void ata_scsi_translate(struct at
- return;
-
- /* data is present; dma-map it */
-- if (cmd->sc_data_direction == SCSI_DATA_READ ||
-- cmd->sc_data_direction == SCSI_DATA_WRITE) {
-+ if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
-+ cmd->sc_data_direction == DMA_TO_DEVICE) {
- if (unlikely(cmd->request_bufflen < 1)) {
- printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
- ap->id, dev->devno);
-@@ -401,7 +686,7 @@ static void ata_scsi_translate(struct at
- ata_sg_init_one(qc, cmd->request_buffer,
- cmd->request_bufflen);
-
-- qc->pci_dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
-+ qc->dma_dir = cmd->sc_data_direction;
- }
-
- qc->complete_fn = ata_scsi_qc_complete;
-@@ -417,6 +702,7 @@ static void ata_scsi_translate(struct at
- return;
-
- err_out:
-+ ata_qc_free(qc);
- ata_bad_cdb(cmd, done);
- DPRINTK("EXIT - badcmd\n");
- }
-@@ -451,7 +737,6 @@ static unsigned int ata_scsi_rbuf_get(st
- buflen = cmd->request_bufflen;
- }
-
-- memset(buf, 0, buflen);
- *buf_out = buf;
- return buflen;
- }
-@@ -459,6 +744,7 @@ static unsigned int ata_scsi_rbuf_get(st
- /**
- * ata_scsi_rbuf_put - Unmap response buffer.
- * @cmd: SCSI command containing buffer to be unmapped.
-+ * @buf: buffer to unmap
- *
- * Unmaps response buffer contained within @cmd.
- *
-@@ -466,19 +752,19 @@ static unsigned int ata_scsi_rbuf_get(st
- * spin_lock_irqsave(host_set lock)
- */
-
--static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd)
-+static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
- {
- if (cmd->use_sg) {
- struct scatterlist *sg;
-
- sg = (struct scatterlist *) cmd->request_buffer;
-- kunmap_atomic(sg->page, KM_USER0);
-+ kunmap_atomic(buf - sg->offset, KM_USER0);
- }
- }
-
- /**
- * ata_scsi_rbuf_fill - wrapper for SCSI command simulators
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @actor: Callback hook for desired SCSI command simulator
- *
- * Takes care of the hard work of simulating a SCSI command...
-@@ -500,8 +786,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
- struct scsi_cmnd *cmd = args->cmd;
-
- buflen = ata_scsi_rbuf_get(cmd, &rbuf);
-+ memset(rbuf, 0, buflen);
- rc = actor(args, rbuf, buflen);
-- ata_scsi_rbuf_put(cmd);
-+ ata_scsi_rbuf_put(cmd, rbuf);
-
- if (rc)
- ata_bad_cdb(cmd, args->done);
-@@ -513,7 +800,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
-
- /**
- * ata_scsiop_inq_std - Simulate INQUIRY command
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -527,28 +814,26 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
- unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
- unsigned int buflen)
- {
-- struct ata_device *dev = args->dev;
--
- u8 hdr[] = {
- TYPE_DISK,
- 0,
- 0x5, /* claim SPC-3 version compatibility */
- 2,
-- 96 - 4
-+ 95 - 4
- };
-
- /* set scsi removeable (RMB) bit per ata bit */
-- if (ata_id_removeable(dev))
-+ if (ata_id_removeable(args->id))
- hdr[1] |= (1 << 7);
-
- VPRINTK("ENTER\n");
-
- memcpy(rbuf, hdr, sizeof(hdr));
-
-- if (buflen > 36) {
-+ if (buflen > 35) {
- memcpy(&rbuf[8], "ATA ", 8);
-- ata_dev_id_string(dev, &rbuf[16], ATA_ID_PROD_OFS, 16);
-- ata_dev_id_string(dev, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
-+ ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
-+ ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
- if (rbuf[32] == 0 || rbuf[32] == ' ')
- memcpy(&rbuf[32], "n/a ", 4);
- }
-@@ -572,7 +857,7 @@ unsigned int ata_scsiop_inq_std(struct a
-
- /**
- * ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -600,7 +885,7 @@ unsigned int ata_scsiop_inq_00(struct at
-
- /**
- * ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -621,8 +906,8 @@ unsigned int ata_scsiop_inq_80(struct at
- };
- memcpy(rbuf, hdr, sizeof(hdr));
-
-- if (buflen > (ATA_SERNO_LEN + 4))
-- ata_dev_id_string(args->dev, (unsigned char *) &rbuf[4],
-+ if (buflen > (ATA_SERNO_LEN + 4 - 1))
-+ ata_dev_id_string(args->id, (unsigned char *) &rbuf[4],
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
-
- return 0;
-@@ -632,7 +917,7 @@ static const char *inq_83_str = "Linux A
-
- /**
- * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -650,7 +935,7 @@ unsigned int ata_scsiop_inq_83(struct at
- rbuf[3] = 4 + strlen(inq_83_str); /* page len */
-
- /* our one and only identification descriptor (vendor-specific) */
-- if (buflen > (strlen(inq_83_str) + 4 + 4)) {
-+ if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
- rbuf[4 + 0] = 2; /* code set: ASCII */
- rbuf[4 + 3] = strlen(inq_83_str);
- memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
-@@ -660,8 +945,8 @@ unsigned int ata_scsiop_inq_83(struct at
- }
-
- /**
-- * ata_scsiop_noop -
-- * @args: Port / device / SCSI command of interest.
-+ * ata_scsiop_noop - Command handler that simply returns success.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -709,7 +994,7 @@ static void ata_msense_push(u8 **ptr_io,
-
- /**
- * ata_msense_caching - Simulate MODE SENSE caching info page
-- * @dev: Device associated with this MODE SENSE command
-+ * @id: device IDENTIFY data
- * @ptr_io: (input/output) Location to store more output data
- * @last: End of output data buffer
- *
-@@ -721,7 +1006,7 @@ static void ata_msense_push(u8 **ptr_io,
- * None.
- */
-
--static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
-+static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
- const u8 *last)
- {
- u8 page[] = {
-@@ -731,9 +1016,9 @@ static unsigned int ata_msense_caching(s
- 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
- };
-
-- if (ata_id_wcache_enabled(dev))
-+ if (ata_id_wcache_enabled(id))
- page[2] |= (1 << 2); /* write cache enable */
-- if (!ata_id_rahead_enabled(dev))
-+ if (!ata_id_rahead_enabled(id))
- page[12] |= (1 << 5); /* disable read ahead */
-
- ata_msense_push(ptr_io, last, page, sizeof(page));
-@@ -754,7 +1039,12 @@ static unsigned int ata_msense_caching(s
-
- static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
- {
-- const u8 page[] = {0xa, 0xa, 2, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
-+ const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
-+
-+ /* byte 2: set the descriptor format sense data bit (bit 2)
-+ * since we need to support returning this format for SAT
-+ * commands and any SCSI commands against a 48b LBA device.
-+ */
-
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
-@@ -787,7 +1077,7 @@ static unsigned int ata_msense_rw_recove
-
- /**
- * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -801,7 +1091,6 @@ unsigned int ata_scsiop_mode_sense(struc
- unsigned int buflen)
- {
- u8 *scsicmd = args->cmd->cmnd, *p, *last;
-- struct ata_device *dev = args->dev;
- unsigned int page_control, six_byte, output_len;
-
- VPRINTK("ENTER\n");
-@@ -829,7 +1118,7 @@ unsigned int ata_scsiop_mode_sense(struc
- break;
-
- case 0x08: /* caching */
-- output_len += ata_msense_caching(dev, &p, last);
-+ output_len += ata_msense_caching(args->id, &p, last);
- break;
-
- case 0x0a: { /* control mode */
-@@ -839,7 +1128,7 @@ unsigned int ata_scsiop_mode_sense(struc
-
- case 0x3f: /* all pages */
- output_len += ata_msense_rw_recovery(&p, last);
-- output_len += ata_msense_caching(dev, &p, last);
-+ output_len += ata_msense_caching(args->id, &p, last);
- output_len += ata_msense_ctl_mode(&p, last);
- break;
-
-@@ -861,7 +1150,7 @@ unsigned int ata_scsiop_mode_sense(struc
-
- /**
- * ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -874,15 +1163,23 @@ unsigned int ata_scsiop_mode_sense(struc
- unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
- unsigned int buflen)
- {
-- u64 n_sectors = args->dev->n_sectors;
-+ u64 n_sectors;
- u32 tmp;
-
- VPRINTK("ENTER\n");
-
-+ if (ata_id_has_lba48(args->id))
-+ n_sectors = ata_id_u64(args->id, 100);
-+ else
-+ n_sectors = ata_id_u32(args->id, 60);
- n_sectors--; /* ATA TotalUserSectors - 1 */
-
-- tmp = n_sectors; /* note: truncates, if lba48 */
- if (args->cmd->cmnd[0] == READ_CAPACITY) {
-+ if( n_sectors >= 0xffffffffULL )
-+ tmp = 0xffffffff ; /* Return max count on overflow */
-+ else
-+ tmp = n_sectors ;
-+
- /* sector count, 32-bit */
- rbuf[0] = tmp >> (8 * 3);
- rbuf[1] = tmp >> (8 * 2);
-@@ -896,10 +1193,12 @@ unsigned int ata_scsiop_read_cap(struct
-
- } else {
- /* sector count, 64-bit */
-- rbuf[2] = n_sectors >> (8 * 7);
-- rbuf[3] = n_sectors >> (8 * 6);
-- rbuf[4] = n_sectors >> (8 * 5);
-- rbuf[5] = n_sectors >> (8 * 4);
-+ tmp = n_sectors >> (8 * 4);
-+ rbuf[2] = tmp >> (8 * 3);
-+ rbuf[3] = tmp >> (8 * 2);
-+ rbuf[4] = tmp >> (8 * 1);
-+ rbuf[5] = tmp;
-+ tmp = n_sectors;
- rbuf[6] = tmp >> (8 * 3);
- rbuf[7] = tmp >> (8 * 2);
- rbuf[8] = tmp >> (8 * 1);
-@@ -916,7 +1215,7 @@ unsigned int ata_scsiop_read_cap(struct
-
- /**
- * ata_scsiop_report_luns - Simulate REPORT LUNS command
-- * @args: Port / device / SCSI command of interest.
-+ * @args: device IDENTIFY data / SCSI command of interest.
- * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
- * @buflen: Response buffer length.
- *
-@@ -964,6 +1263,37 @@ void ata_scsi_badcmd(struct scsi_cmnd *c
- done(cmd);
- }
-
-+static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
-+{
-+ struct scsi_cmnd *cmd = qc->scsicmd;
-+
-+ if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
-+ DPRINTK("request check condition\n");
-+
-+ cmd->result = SAM_STAT_CHECK_CONDITION;
-+
-+ qc->scsidone(cmd);
-+
-+ return 1;
-+ } else {
-+ u8 *scsicmd = cmd->cmnd;
-+
-+ if (scsicmd[0] == INQUIRY) {
-+ u8 *buf = NULL;
-+ unsigned int buflen;
-+
-+ buflen = ata_scsi_rbuf_get(cmd, &buf);
-+ buf[2] = 0x5;
-+ buf[3] = (buf[3] & 0xf0) | 2;
-+ ata_scsi_rbuf_put(cmd, buf);
-+ }
-+ cmd->result = SAM_STAT_GOOD;
-+ }
-+
-+ qc->scsidone(cmd);
-+
-+ return 0;
-+}
- /**
- * atapi_xlat - Initialize PACKET taskfile
- * @qc: command structure to be initialized
-@@ -979,45 +1309,58 @@ void ata_scsi_badcmd(struct scsi_cmnd *c
- static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
- {
- struct scsi_cmnd *cmd = qc->scsicmd;
-+ struct ata_device *dev = qc->dev;
-+ int using_pio = (dev->flags & ATA_DFLAG_PIO);
-+ int nodata = (cmd->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, qc->ap->cdb_len);
-+
-+ qc->complete_fn = atapi_qc_complete;
-
- qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-- if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
-+ if (cmd->sc_data_direction == DMA_TO_DEVICE) {
- qc->tf.flags |= ATA_TFLAG_WRITE;
- DPRINTK("direction: write\n");
- }
-
- qc->tf.command = ATA_CMD_PACKET;
-
-- /* no data - interrupt-driven */
-- if (cmd->sc_data_direction == SCSI_DATA_NONE)
-- qc->tf.protocol = ATA_PROT_ATAPI;
--
-- /* PIO data xfer - polling */
-- else if ((qc->flags & ATA_QCFLAG_DMA) == 0) {
-- ata_qc_set_polling(qc);
-- qc->tf.protocol = ATA_PROT_ATAPI;
-+ /* no data, or PIO data xfer */
-+ if (using_pio || nodata) {
-+ if (nodata)
-+ qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
-+ else
-+ qc->tf.protocol = ATA_PROT_ATAPI;
- qc->tf.lbam = (8 * 1024) & 0xff;
- qc->tf.lbah = (8 * 1024) >> 8;
-+ }
-
-- /* DMA data xfer - interrupt-driven */
-- } else {
-+ /* DMA data xfer */
-+ else {
- qc->tf.protocol = ATA_PROT_ATAPI_DMA;
- qc->tf.feature |= ATAPI_PKT_DMA;
-
- #ifdef ATAPI_ENABLE_DMADIR
- /* some SATA bridges need us to indicate data xfer direction */
-- if (cmd->sc_data_direction != SCSI_DATA_WRITE)
-+ if (cmd->sc_data_direction != DMA_TO_DEVICE)
- qc->tf.feature |= ATAPI_DMADIR;
- #endif
- }
-
-+ qc->nbytes = cmd->bufflen;
-+
- return 0;
- }
-
- /**
- * ata_scsi_find_dev - lookup ata_device from scsi_cmnd
- * @ap: ATA port to which the device is attached
-- * @cmd: SCSI command to be sent to the device
-+ * @scsidev: SCSI device from which we derive the ATA device
- *
- * Given various information provided in struct scsi_cmnd,
- * map that onto an ATA bus, and using that mapping
-@@ -1031,19 +1374,19 @@ static unsigned int atapi_xlat(struct at
- * Associated ATA device, or %NULL if not found.
- */
-
--static inline struct ata_device *
--ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
-+struct ata_device *
-+ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
- {
- struct ata_device *dev;
-
- /* skip commands not addressed to targets we simulate */
-- if (likely(cmd->device->id < ATA_MAX_DEVICES))
-- dev = &ap->device[cmd->device->id];
-+ if (likely(scsidev->id < ATA_MAX_DEVICES))
-+ dev = &ap->device[scsidev->id];
- else
- return NULL;
-
-- if (unlikely((cmd->device->channel != 0) ||
-- (cmd->device->lun != 0)))
-+ if (unlikely((scsidev->channel != 0) ||
-+ (scsidev->lun != 0)))
- return NULL;
-
- if (unlikely(!ata_dev_present(dev)))
-@@ -1059,6 +1402,7 @@ ata_scsi_find_dev(struct ata_port *ap, s
-
- /**
- * ata_get_xlat_func - check if SCSI to ATA translation is possible
-+ * @dev: ATA device
- * @cmd: SCSI command opcode to consider
- *
- * Look up the SCSI command given, and determine whether the
-@@ -1068,7 +1412,7 @@ ata_scsi_find_dev(struct ata_port *ap, s
- * Pointer to translation function if possible, %NULL if not.
- */
-
--static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd)
-+static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
- {
- switch (cmd) {
- case READ_6:
-@@ -1079,6 +1423,15 @@ static inline ata_xlat_func_t ata_get_xl
- case WRITE_10:
- case WRITE_16:
- return ata_scsi_rw_xlat;
-+
-+ case SYNCHRONIZE_CACHE:
-+ if (ata_try_flush_cache(dev))
-+ return ata_scsi_flush_xlat;
-+ break;
-+
-+ case VERIFY:
-+ case VERIFY_16:
-+ return ata_scsi_verify_xlat;
- }
-
- return NULL;
-@@ -1096,11 +1449,12 @@ static inline void ata_scsi_dump_cdb(str
- struct scsi_cmnd *cmd)
- {
- #ifdef ATA_DEBUG
-+ struct scsi_device *scsidev = cmd->device;
- u8 *scsicmd = cmd->cmnd;
-
- DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ap->id,
-- cmd->device->channel, cmd->device->id, cmd->device->lun,
-+ scsidev->channel, scsidev->id, scsidev->lun,
- scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
- scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
- scsicmd[8]);
-@@ -1130,12 +1484,13 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
- {
- struct ata_port *ap;
- struct ata_device *dev;
-+ struct scsi_device *scsidev = cmd->device;
-
-- ap = (struct ata_port *) &cmd->device->host->hostdata[0];
-+ ap = (struct ata_port *) &scsidev->host->hostdata[0];
-
- ata_scsi_dump_cdb(ap, cmd);
-
-- dev = ata_scsi_find_dev(ap, cmd);
-+ dev = ata_scsi_find_dev(ap, scsidev);
- if (unlikely(!dev)) {
- cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
-@@ -1143,12 +1498,13 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
- }
-
- if (dev->class == ATA_DEV_ATA) {
-- ata_xlat_func_t xlat_func = ata_get_xlat_func(cmd->cmnd[0]);
-+ ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
-+ cmd->cmnd[0]);
-
- if (xlat_func)
- ata_scsi_translate(ap, dev, cmd, done, xlat_func);
- else
-- ata_scsi_simulate(ap, dev, cmd, done);
-+ ata_scsi_simulate(dev->id, cmd, done);
- } else
- ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
-
-@@ -1158,8 +1514,7 @@ out_unlock:
-
- /**
- * ata_scsi_simulate - simulate SCSI command on ATA device
-- * @ap: Port to which ATA device is attached.
-- * @dev: Target device for CDB.
-+ * @id: current IDENTIFY data for target device.
- * @cmd: SCSI command being sent to device.
- * @done: SCSI command completion function.
- *
-@@ -1170,21 +1525,20 @@ out_unlock:
- * spin_lock_irqsave(host_set lock)
- */
-
--static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
-- struct scsi_cmnd *cmd,
-- void (*done)(struct scsi_cmnd *))
-+void ata_scsi_simulate(u16 *id,
-+ struct scsi_cmnd *cmd,
-+ void (*done)(struct scsi_cmnd *))
- {
- struct ata_scsi_args args;
- u8 *scsicmd = cmd->cmnd;
-
-- args.ap = ap;
-- args.dev = dev;
-+ args.id = id;
- args.cmd = cmd;
- args.done = done;
-
- switch(scsicmd[0]) {
- /* no-op's, complete with success */
-- case SYNCHRONIZE_CACHE: /* FIXME: temporary */
-+ case SYNCHRONIZE_CACHE:
- case REZERO_UNIT:
- case SEEK_6:
- case SEEK_10:
---- ./include/linux/libata.h.libata 2005-09-26 13:31:45.000000000 +0400
-+++ ./include/linux/libata.h 2005-10-26 14:55:17.007915184 +0400
-@@ -25,6 +25,7 @@
-
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/pci.h>
- #include <asm/io.h>
- #include <linux/ata.h>
- #include <linux/workqueue.h>
-@@ -32,7 +33,6 @@
- /*
- * compile-time options
- */
--#undef ATA_FORCE_PIO /* do not configure or use DMA */
- #undef ATA_DEBUG /* debugging output */
- #undef ATA_VERBOSE_DEBUG /* yet more debugging output */
- #undef ATA_IRQ_TRAP /* define to ack screaming irqs */
-@@ -69,6 +69,12 @@
- /* defines only for the constants which don't work well as enums */
- #define ATA_TAG_POISON 0xfafbfcfdU
-
-+/* move to PCI layer? */
-+static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
-+{
-+ return &pdev->dev;
-+}
-+
- enum {
- /* various global constants */
- LIBATA_MAX_PRD = ATA_MAX_PRD / 2,
-@@ -88,10 +94,7 @@ enum {
- /* struct ata_device stuff */
- ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
- ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
-- ATA_DFLAG_MASTER = (1 << 2), /* is device 0? */
-- ATA_DFLAG_WCACHE = (1 << 3), /* has write cache we can
-- * (hopefully) flush? */
-- ATA_DFLAG_LOCK_SECTORS = (1 << 4), /* don't adjust max_sectors */
-+ ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */
-
- ATA_DEV_UNKNOWN = 0, /* unknown device */
- ATA_DEV_ATA = 1, /* ATA device */
-@@ -109,9 +112,9 @@ enum {
- ATA_FLAG_SRST = (1 << 5), /* use ATA SRST, not E.D.D. */
- ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */
- ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
-+ ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */
-
- ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
-- ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
- ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */
- ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */
- ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
-@@ -140,6 +143,13 @@ enum {
- PORT_UNKNOWN = 0,
- PORT_ENABLED = 1,
- PORT_DISABLED = 2,
-+
-+ /* encoding various smaller bitmaps into a single
-+ * unsigned long bitmap
-+ */
-+ ATA_SHIFT_UDMA = 0,
-+ ATA_SHIFT_MWDMA = 8,
-+ ATA_SHIFT_PIO = 11,
- };
-
- enum pio_task_states {
-@@ -182,26 +192,28 @@ struct ata_ioports {
-
- struct ata_probe_ent {
- struct list_head node;
-- struct pci_dev *pdev;
-+ struct device *dev;
- struct ata_port_operations *port_ops;
- Scsi_Host_Template *sht;
- struct ata_ioports port[ATA_MAX_PORTS];
- unsigned int n_ports;
-+ unsigned int hard_port_no;
- unsigned int pio_mask;
-+ unsigned int mwdma_mask;
- unsigned int udma_mask;
- unsigned int legacy_mode;
- unsigned long irq;
- unsigned int irq_flags;
- unsigned long host_flags;
-- void *mmio_base;
-+ void __iomem *mmio_base;
- void *private_data;
- };
-
- struct ata_host_set {
- spinlock_t lock;
-- struct pci_dev *pdev;
-+ struct device *dev;
- unsigned long irq;
-- void *mmio_base;
-+ void __iomem *mmio_base;
- unsigned int n_ports;
- void *private_data;
- struct ata_port_operations *ops;
-@@ -215,18 +227,24 @@ struct ata_queued_cmd {
- struct scsi_cmnd *scsicmd;
- void (*scsidone)(struct scsi_cmnd *);
-
-+ struct ata_taskfile tf;
-+ u8 cdb[ATAPI_CDB_LEN];
-+
- unsigned long flags; /* ATA_QCFLAG_xxx */
- unsigned int tag;
- unsigned int n_elem;
-
-- int pci_dma_dir;
-+ int dma_dir;
-
- unsigned int nsect;
- unsigned int cursect;
-+
-+ unsigned int nbytes;
-+ unsigned int curbytes;
-+
- unsigned int cursg;
- unsigned int cursg_ofs;
-
-- struct ata_taskfile tf;
- struct scatterlist sgent;
- void *buf_virt;
-
-@@ -251,8 +269,10 @@ struct ata_device {
- unsigned int class; /* ATA_DEV_xxx */
- unsigned int devno; /* 0 or 1 */
- u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
-- unsigned int pio_mode;
-- unsigned int udma_mode;
-+ u8 pio_mode;
-+ u8 dma_mode;
-+ u8 xfer_mode;
-+ unsigned int xfer_shift; /* ATA_SHIFT_xxx */
-
- /* cache info about current transfer mode */
- u8 xfer_protocol; /* taskfile xfer protocol */
-@@ -266,6 +286,7 @@ struct ata_port {
- unsigned long flags; /* ATA_FLAG_xxx */
- unsigned int id; /* unique id req'd by scsi midlyr */
- unsigned int port_no; /* unique port #; from zero */
-+ unsigned int hard_port_no; /* hardware port #; from zero */
-
- struct ata_prd *prd; /* our SG list */
- dma_addr_t prd_dma; /* and its DMA mapping */
-@@ -277,8 +298,10 @@ struct ata_port {
- unsigned int bus_state;
- unsigned int port_state;
- unsigned int pio_mask;
-+ unsigned int mwdma_mask;
- unsigned int udma_mask;
- unsigned int cbl; /* cable type; ATA_CBL_xxx */
-+ unsigned int cdb_len;
-
- struct ata_device device[ATA_MAX_DEVICES];
-
-@@ -303,20 +326,23 @@ struct ata_port_operations {
-
- void (*dev_config) (struct ata_port *, struct ata_device *);
-
-- void (*set_piomode) (struct ata_port *, struct ata_device *,
-- unsigned int);
-- void (*set_udmamode) (struct ata_port *, struct ata_device *,
-- unsigned int);
-+ void (*set_piomode) (struct ata_port *, struct ata_device *);
-+ void (*set_dmamode) (struct ata_port *, struct ata_device *);
-
- void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
- void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
-
- void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
- u8 (*check_status)(struct ata_port *ap);
-+ u8 (*check_altstatus)(struct ata_port *ap);
-+ u8 (*check_err)(struct ata_port *ap);
-+ void (*dev_select)(struct ata_port *ap, unsigned int device);
-
- void (*phy_reset) (struct ata_port *ap);
- void (*post_set_mode) (struct ata_port *ap);
-
-+ int (*check_atapi_dma) (struct ata_queued_cmd *qc);
-+
- void (*bmdma_setup) (struct ata_queued_cmd *qc);
- void (*bmdma_start) (struct ata_queued_cmd *qc);
-
-@@ -336,33 +362,35 @@ struct ata_port_operations {
- void (*port_stop) (struct ata_port *ap);
-
- void (*host_stop) (struct ata_host_set *host_set);
-+
-+ void (*bmdma_stop) (struct ata_port *ap);
-+ u8 (*bmdma_status) (struct ata_port *ap);
- };
-
- struct ata_port_info {
- Scsi_Host_Template *sht;
- unsigned long host_flags;
- unsigned long pio_mask;
-+ unsigned long mwdma_mask;
- unsigned long udma_mask;
- struct ata_port_operations *port_ops;
- };
-
--struct pci_bits {
-- unsigned int reg; /* PCI config register to read */
-- unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
-- unsigned long mask;
-- unsigned long val;
--};
-
- extern void ata_port_probe(struct ata_port *);
-+extern void __sata_phy_reset(struct ata_port *ap);
- extern void sata_phy_reset(struct ata_port *ap);
- extern void ata_bus_reset(struct ata_port *ap);
- extern void ata_port_disable(struct ata_port *);
- extern void ata_std_ports(struct ata_ioports *ioaddr);
-+#ifdef CONFIG_PCI
- extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
- unsigned int n_ports);
- extern void ata_pci_remove_one (struct pci_dev *pdev);
-+#endif /* CONFIG_PCI */
- extern int ata_device_add(struct ata_probe_ent *ent);
- extern int ata_scsi_detect(Scsi_Host_Template *sht);
-+extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
- extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
- extern int ata_scsi_error(struct Scsi_Host *host);
- extern int ata_scsi_release(struct Scsi_Host *host);
-@@ -370,18 +398,19 @@ extern unsigned int ata_host_intr(struct
- /*
- * Default driver ops implementations
- */
--extern void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf);
--extern void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
--extern void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf);
--extern void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-+extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf);
-+extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
- extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp);
- extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
--extern u8 ata_check_status_pio(struct ata_port *ap);
--extern u8 ata_check_status_mmio(struct ata_port *ap);
--extern void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf);
--extern void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-+extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
-+extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
-+extern u8 ata_check_status(struct ata_port *ap);
-+extern u8 ata_altstatus(struct ata_port *ap);
-+extern u8 ata_chk_err(struct ata_port *ap);
-+extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
- extern int ata_port_start (struct ata_port *ap);
- extern void ata_port_stop (struct ata_port *ap);
-+extern void ata_host_stop (struct ata_host_set *host_set);
- extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
- extern void ata_qc_prep(struct ata_queued_cmd *qc);
- extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
-@@ -389,20 +418,41 @@ extern void ata_sg_init_one(struct ata_q
- unsigned int buflen);
- extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
- unsigned int n_elem);
--extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
-+extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
-+extern void ata_dev_id_string(u16 *id, unsigned char *s,
- unsigned int ofs, unsigned int len);
--extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
--extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
--extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);
--extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
-+extern void ata_dev_config(struct ata_port *ap, unsigned int i);
-+extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
-+extern void ata_bmdma_start (struct ata_queued_cmd *qc);
-+extern void ata_bmdma_stop(struct ata_port *ap);
-+extern u8 ata_bmdma_status(struct ata_port *ap);
- extern void ata_bmdma_irq_clear(struct ata_port *ap);
--extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
- extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
- extern void ata_eng_timeout(struct ata_port *ap);
-+extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
-+ void (*done)(struct scsi_cmnd *));
- extern int ata_std_bios_param(struct scsi_device *sdev,
- struct block_device *bdev,
- sector_t capacity, int geom[]);
- extern int ata_scsi_slave_config(struct scsi_device *sdev);
-+extern int ata_scsi_dump_sanity_check(struct scsi_device *sdev);
-+extern int ata_scsi_dump_quiesce(struct scsi_device *sdev);
-+extern void ata_scsi_dump_poll(struct scsi_device *sdev);
-+
-+
-+#ifdef CONFIG_PCI
-+struct pci_bits {
-+ unsigned int reg; /* PCI config register to read */
-+ unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
-+ unsigned long mask;
-+ unsigned long val;
-+};
-+
-+extern struct ata_probe_ent *
-+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
-+extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
-+
-+#endif /* CONFIG_PCI */
-
-
- static inline unsigned int ata_tag_valid(unsigned int tag)
-@@ -416,25 +466,19 @@ static inline unsigned int ata_dev_prese
- (dev->class == ATA_DEV_ATAPI));
- }
-
--static inline u8 ata_chk_err(struct ata_port *ap)
--{
-- if (ap->flags & ATA_FLAG_MMIO) {
-- return readb((void *) ap->ioaddr.error_addr);
-- }
-- return inb(ap->ioaddr.error_addr);
--}
--
- static inline u8 ata_chk_status(struct ata_port *ap)
- {
- return ap->ops->check_status(ap);
- }
-
--static inline u8 ata_altstatus(struct ata_port *ap)
--{
-- if (ap->flags & ATA_FLAG_MMIO)
-- return readb(ap->ioaddr.altstatus_addr);
-- return inb(ap->ioaddr.altstatus_addr);
--}
-+
-+/**
-+ * ata_pause - Flush writes and pause 400 nanoseconds.
-+ * @ap: Port to wait for.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-
- static inline void ata_pause(struct ata_port *ap)
- {
-@@ -442,6 +486,19 @@ static inline void ata_pause(struct ata_
- ndelay(400);
- }
-
-+
-+/**
-+ * ata_busy_wait - Wait for a port status register
-+ * @ap: Port to wait for.
-+ *
-+ * Waits up to max*10 microseconds for the selected bits in the port's
-+ * status register to be cleared.
-+ * Returns final value of status register.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+
- static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
- unsigned int max)
- {
-@@ -456,6 +513,18 @@ static inline u8 ata_busy_wait(struct at
- return status;
- }
-
-+
-+/**
-+ * ata_wait_idle - Wait for a port to be idle.
-+ * @ap: Port to wait for.
-+ *
-+ * Waits up to 10ms for port's BUSY and DRQ signals to clear.
-+ * Returns final value of status register.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+
- static inline u8 ata_wait_idle(struct ata_port *ap)
- {
- u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
-@@ -472,7 +541,6 @@ static inline u8 ata_wait_idle(struct at
-
- static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
- {
-- qc->flags &= ~ATA_QCFLAG_DMA;
- qc->tf.ctl |= ATA_NIEN;
- }
-
-@@ -495,6 +563,18 @@ static inline void ata_tf_init(struct at
- tf->device = ATA_DEVICE_OBS | ATA_DEV1;
- }
-
-+
-+/**
-+ * ata_irq_on - Enable interrupts on a port.
-+ * @ap: Port on which interrupts are enabled.
-+ *
-+ * Enable interrupts on a legacy IDE device using MMIO or PIO,
-+ * wait for idle, clear any pending interrupts.
-+ *
-+ * LOCKING:
-+ * Inherited from caller.
-+ */
-+
- static inline u8 ata_irq_on(struct ata_port *ap)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-@@ -504,7 +584,7 @@ static inline u8 ata_irq_on(struct ata_p
- ap->last_ctl = ap->ctl;
-
- if (ap->flags & ATA_FLAG_MMIO)
-- writeb(ap->ctl, ioaddr->ctl_addr);
-+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
- tmp = ata_wait_idle(ap);
-@@ -514,6 +594,18 @@ static inline u8 ata_irq_on(struct ata_p
- return tmp;
- }
-
-+
-+/**
-+ * ata_irq_ack - Acknowledge a device interrupt.
-+ * @ap: Port on which interrupts are enabled.
-+ *
-+ * Wait up to 10 ms for legacy IDE device to become idle (BUSY
-+ * or BUSY+DRQ clear). Obtain dma status and port status from
-+ * device. Clear the interrupt. Return port status.
-+ *
-+ * LOCKING:
-+ */
-+
- static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
- {
- unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-@@ -525,7 +617,7 @@ static inline u8 ata_irq_ack(struct ata_
-
- /* get controller status; clear intr, err bits */
- if (ap->flags & ATA_FLAG_MMIO) {
-- void *mmio = (void *) ap->ioaddr.bmdma_addr;
-+ void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
- host_stat = readb(mmio + ATA_DMA_STATUS);
- writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- mmio + ATA_DMA_STATUS);
-@@ -555,49 +647,23 @@ static inline void scr_write(struct ata_
- ap->ops->scr_write(ap, reg, val);
- }
-
--static inline unsigned int sata_dev_present(struct ata_port *ap)
-+static inline void scr_write_flush(struct ata_port *ap, unsigned int reg,
-+ u32 val)
- {
-- return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
--}
--
--static inline void ata_bmdma_stop(struct ata_port *ap)
--{
-- if (ap->flags & ATA_FLAG_MMIO) {
-- void *mmio = (void *) ap->ioaddr.bmdma_addr;
--
-- /* clear start/stop bit */
-- writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
-- mmio + ATA_DMA_CMD);
-- } else {
-- /* clear start/stop bit */
-- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
-- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-- }
--
-- /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-- ata_altstatus(ap); /* dummy read */
-+ ap->ops->scr_write(ap, reg, val);
-+ (void) ap->ops->scr_read(ap, reg);
- }
-
--static inline void ata_bmdma_ack_irq(struct ata_port *ap)
-+static inline unsigned int sata_dev_present(struct ata_port *ap)
- {
-- if (ap->flags & ATA_FLAG_MMIO) {
-- void *mmio = ((void *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
-- writeb(readb(mmio), mmio);
-- } else {
-- unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
-- outb(inb(addr), addr);
-- }
-+ return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
- }
-
--static inline u8 ata_bmdma_status(struct ata_port *ap)
-+static inline int ata_try_flush_cache(struct ata_device *dev)
- {
-- u8 host_stat;
-- if (ap->flags & ATA_FLAG_MMIO) {
-- void *mmio = (void *) ap->ioaddr.bmdma_addr;
-- host_stat = readb(mmio + ATA_DMA_STATUS);
-- } else
-- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-- return host_stat;
-+ return ata_id_wcache_enabled(dev->id) ||
-+ ata_id_has_flush(dev->id) ||
-+ ata_id_has_flush_ext(dev->id);
- }
-
- #endif /* __LINUX_LIBATA_H__ */
---- ./include/linux/ata.h.libata 2005-09-26 13:31:47.000000000 +0400
-+++ ./include/linux/ata.h 2005-10-26 14:55:17.009914880 +0400
-@@ -24,6 +24,8 @@
- #ifndef __LINUX_ATA_H__
- #define __LINUX_ATA_H__
-
-+#include <linux/types.h>
-+
- /* defines only for the constants which don't work well as enums */
- #define ATA_DMA_BOUNDARY 0xffffUL
- #define ATA_DMA_MASK 0xffffffffULL
-@@ -33,8 +35,6 @@ enum {
- ATA_MAX_DEVICES = 2, /* per bus/port */
- ATA_MAX_PRD = 256, /* we could make these 256/256 */
- ATA_SECT_SIZE = 512,
-- ATA_SECT_SIZE_MASK = (ATA_SECT_SIZE - 1),
-- ATA_SECT_DWORDS = ATA_SECT_SIZE / sizeof(u32),
-
- ATA_ID_WORDS = 256,
- ATA_ID_PROD_OFS = 27,
-@@ -42,6 +42,7 @@ enum {
- ATA_ID_SERNO_OFS = 10,
- ATA_ID_MAJOR_VER = 80,
- ATA_ID_PIO_MODES = 64,
-+ ATA_ID_MWDMA_MODES = 63,
- ATA_ID_UDMA_MODES = 88,
- ATA_ID_PIO4 = (1 << 1),
-
-@@ -122,6 +123,8 @@ enum {
- ATA_CMD_PIO_WRITE_EXT = 0x34,
- ATA_CMD_SET_FEATURES = 0xEF,
- ATA_CMD_PACKET = 0xA0,
-+ ATA_CMD_VERIFY = 0x40,
-+ ATA_CMD_VERIFY_EXT = 0x42,
-
- /* SETFEATURES stuff */
- SETFEATURES_XFER = 0x03,
-@@ -133,13 +136,24 @@ enum {
- XFER_UDMA_2 = 0x42,
- XFER_UDMA_1 = 0x41,
- XFER_UDMA_0 = 0x40,
-+ XFER_MW_DMA_2 = 0x22,
-+ XFER_MW_DMA_1 = 0x21,
-+ XFER_MW_DMA_0 = 0x20,
- XFER_PIO_4 = 0x0C,
- XFER_PIO_3 = 0x0B,
-+ XFER_PIO_2 = 0x0A,
-+ XFER_PIO_1 = 0x09,
-+ XFER_PIO_0 = 0x08,
-+ XFER_SW_DMA_2 = 0x12,
-+ XFER_SW_DMA_1 = 0x11,
-+ XFER_SW_DMA_0 = 0x10,
-+ XFER_PIO_SLOW = 0x00,
-
- /* ATAPI stuff */
- ATAPI_PKT_DMA = (1 << 0),
- ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
- 0=to device, 1=to host */
-+ ATAPI_CDB_LEN = 16,
-
- /* cable types */
- ATA_CBL_NONE = 0,
-@@ -169,16 +183,22 @@ enum ata_tf_protocols {
- ATA_PROT_PIO, /* PIO single sector */
- ATA_PROT_PIO_MULT, /* PIO multiple sector */
- ATA_PROT_DMA, /* DMA */
-- ATA_PROT_ATAPI, /* packet command */
-+ ATA_PROT_ATAPI, /* packet command, PIO data xfer*/
-+ ATA_PROT_ATAPI_NODATA, /* packet command, no data */
- ATA_PROT_ATAPI_DMA, /* packet command with special DMA sauce */
- };
-
-+enum ata_ioctls {
-+ ATA_IOC_GET_IO32 = 0x309,
-+ ATA_IOC_SET_IO32 = 0x324,
-+};
-+
- /* core structures */
-
- struct ata_prd {
- u32 addr;
- u32 flags_len;
--} __attribute__((packed));
-+};
-
- struct ata_taskfile {
- unsigned long flags; /* ATA_TFLAG_xxx */
-@@ -203,26 +223,40 @@ struct ata_taskfile {
- u8 command; /* IO operation */
- };
-
--#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
--#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
--#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
--#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
--#define ata_id_has_wcache(dev) ((dev)->id[82] & (1 << 5))
--#define ata_id_has_pm(dev) ((dev)->id[82] & (1 << 3))
--#define ata_id_has_lba(dev) ((dev)->id[49] & (1 << 9))
--#define ata_id_has_dma(dev) ((dev)->id[49] & (1 << 8))
--#define ata_id_removeable(dev) ((dev)->id[0] & (1 << 7))
--#define ata_id_u32(dev,n) \
-- (((u32) (dev)->id[(n) + 1] << 16) | ((u32) (dev)->id[(n)]))
--#define ata_id_u64(dev,n) \
-- ( ((u64) dev->id[(n) + 3] << 48) | \
-- ((u64) dev->id[(n) + 2] << 32) | \
-- ((u64) dev->id[(n) + 1] << 16) | \
-- ((u64) dev->id[(n) + 0]) )
-+#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
-+#define ata_id_is_sata(id) ((id)[93] == 0)
-+#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
-+#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
-+#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
-+#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
-+#define ata_id_has_lba48(id) ((id)[83] & (1 << 10))
-+#define ata_id_has_wcache(id) ((id)[82] & (1 << 5))
-+#define ata_id_has_pm(id) ((id)[82] & (1 << 3))
-+#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
-+#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
-+#define ata_id_removeable(id) ((id)[0] & (1 << 7))
-+#define ata_id_u32(id,n) \
-+ (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
-+#define ata_id_u64(id,n) \
-+ ( ((u64) (id)[(n) + 3] << 48) | \
-+ ((u64) (id)[(n) + 2] << 32) | \
-+ ((u64) (id)[(n) + 1] << 16) | \
-+ ((u64) (id)[(n) + 0]) )
-+
-+static inline int atapi_cdb_len(u16 *dev_id)
-+{
-+ u16 tmp = dev_id[0] & 0x3;
-+ switch (tmp) {
-+ case 0: return 12;
-+ case 1: return 16;
-+ default: return -1;
-+ }
-+}
-
- static inline int is_atapi_taskfile(struct ata_taskfile *tf)
- {
- return (tf->protocol == ATA_PROT_ATAPI) ||
-+ (tf->protocol == ATA_PROT_ATAPI_NODATA) ||
- (tf->protocol == ATA_PROT_ATAPI_DMA);
- }
-
---- ./include/scsi/scsi.h.libata 2005-09-26 13:32:02.000000000 +0400
-+++ ./include/scsi/scsi.h 2005-10-26 14:55:17.009914880 +0400
-@@ -108,6 +108,7 @@ extern const char *const scsi_device_typ
- #define WRITE_LONG_2 0xea
- #define READ_16 0x88
- #define WRITE_16 0x8a
-+#define VERIFY_16 0x8f
- #define SERVICE_ACTION_IN 0x9e
- /* values for service action in */
- #define SAI_READ_CAPACITY_16 0x10
-@@ -353,14 +354,19 @@ struct scsi_lun {
- ((lun) & 0x07))
-
- /*
-- * SCSI command sets
-+ * struct scsi_device::scsi_level values. For SCSI devices other than those
-+ * prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1)
-+ * where "resp" is a byte array of the response to an INQUIRY. The scsi_level
-+ * variable is visible to the user via sysfs.
- */
-
- #define SCSI_UNKNOWN 0
- #define SCSI_1 1
- #define SCSI_1_CCS 2
- #define SCSI_2 3
--#define SCSI_3 4
-+#define SCSI_3 4 /* SPC */
-+#define SCSI_SPC_2 5
-+#define SCSI_SPC_3 6
-
- /*
- * INQ PERIPHERAL QUALIFIERS
---- ./include/scsi/scsi_host.h.libata 2005-10-26 14:54:51.644770968 +0400
-+++ ./include/scsi/scsi_host.h 2005-10-26 14:55:54.577203784 +0400
-@@ -370,6 +370,45 @@ struct scsi_host_template {
- * module_init/module_exit.
- */
- struct list_head legacy_hosts;
-+
-+ /* operations for dump */
-+
-+ /*
-+ * dump_sanity_check() checks if the selected device works normally.
-+ * A device which returns an error status will not be selected as
-+ * the dump device.
-+ *
-+ * Status: OPTIONAL
-+ */
-+ int (* dump_sanity_check)(struct scsi_device *);
-+
-+ /*
-+ * dump_quiesce() is called after the device is selected as the
-+ * dump device. Usually, host reset is executed and Write Cache
-+ * Enable bit of the disk device is temporarily set for the
-+ * dump operation.
-+ *
-+ * Status: OPTIONAL
-+ */
-+ int (* dump_quiesce)(struct scsi_device *);
-+
-+ /*
-+ * dump_shutdown() is called after dump is completed. Usually
-+ * "SYNCHRONIZE CACHE" command is issued to the disk.
-+ *
-+ * Status: OPTIONAL
-+ */
-+ int (* dump_shutdown)(struct scsi_device *);
-+
-+ /*
-+ * dump_poll() should call the interrupt handler. It is called
-+ * repeatedly after queuecommand() is issued, and until the command
-+ * is completed. If the low level device driver support crash dump,
-+ * it must have this routine.
-+ *
-+ * Status: OPTIONAL
-+ */
-+ void (* dump_poll)(struct scsi_device *);
- };
-
- /*
-@@ -534,7 +580,7 @@ struct Scsi_Host {
-
-
- extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
--extern int scsi_add_host(struct Scsi_Host *, struct device *);
-+extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
- extern void scsi_scan_host(struct Scsi_Host *);
- extern void scsi_remove_host(struct Scsi_Host *);
- extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
---- ./drivers/scsi/ahci.c.libata 1970-01-01 03:00:00.000000000 +0300
-+++ ./drivers/scsi/ahci.c 2005-10-19 11:47:14.000000000 +0400
-@@ -0,0 +1,1110 @@
-+/*
-+ * ahci.c - AHCI SATA support
-+ *
-+ * Copyright 2004 Red Hat, Inc.
-+ *
-+ * The contents of this file are subject to the Open
-+ * Software License version 1.1 that can be found at
-+ * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
-+ * by reference.
-+ *
-+ * Alternatively, the contents of this file may be used under the terms
-+ * of the GNU General Public License version 2 (the "GPL") as distributed
-+ * in the kernel source COPYING file, in which case the provisions of
-+ * the GPL are applicable instead of the above. If you wish to allow
-+ * the use of your version of this file only under the terms of the
-+ * GPL and not to allow others to use your version of this file under
-+ * the OSL, indicate your decision by deleting the provisions above and
-+ * replace them with the notice and other provisions required by the GPL.
-+ * If you do not delete the provisions above, a recipient may use your
-+ * version of this file under either the OSL or the GPL.
-+ *
-+ * Version 1.0 of the AHCI specification:
-+ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/dma-mapping.h>
-+#include "scsi.h"
-+#include <scsi/scsi_host.h>
-+#include <linux/libata.h>
-+#include <asm/io.h>
-+
-+#define DRV_NAME "ahci"
-+#define DRV_VERSION "1.01"
-+
-+
-+enum {
-+ AHCI_PCI_BAR = 5,
-+ AHCI_MAX_SG = 168, /* hardware max is 64K */
-+ AHCI_DMA_BOUNDARY = 0xffffffff,
-+ AHCI_USE_CLUSTERING = 0,
-+ AHCI_CMD_SLOT_SZ = 32 * 32,
-+ AHCI_RX_FIS_SZ = 256,
-+ AHCI_CMD_TBL_HDR = 0x80,
-+ AHCI_CMD_TBL_CDB = 0x40,
-+ AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
-+ AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
-+ AHCI_RX_FIS_SZ,
-+ AHCI_IRQ_ON_SG = (1 << 31),
-+ AHCI_CMD_ATAPI = (1 << 5),
-+ AHCI_CMD_WRITE = (1 << 6),
-+
-+ RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
-+
-+ board_ahci = 0,
-+
-+ /* global controller registers */
-+ HOST_CAP = 0x00, /* host capabilities */
-+ HOST_CTL = 0x04, /* global host control */
-+ HOST_IRQ_STAT = 0x08, /* interrupt status */
-+ HOST_PORTS_IMPL = 0x0c, /* bitmap of implemented ports */
-+ HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
-+
-+ /* HOST_CTL bits */
-+ HOST_RESET = (1 << 0), /* reset controller; self-clear */
-+ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */
-+ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
-+
-+ /* HOST_CAP bits */
-+ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
-+
-+ /* registers for each SATA port */
-+ PORT_LST_ADDR = 0x00, /* command list DMA addr */
-+ PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
-+ PORT_FIS_ADDR = 0x08, /* FIS rx buf addr */
-+ PORT_FIS_ADDR_HI = 0x0c, /* FIS rx buf addr hi */
-+ PORT_IRQ_STAT = 0x10, /* interrupt status */
-+ PORT_IRQ_MASK = 0x14, /* interrupt enable/disable mask */
-+ PORT_CMD = 0x18, /* port command */
-+ PORT_TFDATA = 0x20, /* taskfile data */
-+ PORT_SIG = 0x24, /* device TF signature */
-+ PORT_CMD_ISSUE = 0x38, /* command issue */
-+ PORT_SCR = 0x28, /* SATA phy register block */
-+ PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */
-+ PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */
-+ PORT_SCR_ERR = 0x30, /* SATA phy register: SError */
-+ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
-+
-+ /* PORT_IRQ_{STAT,MASK} bits */
-+ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
-+ PORT_IRQ_TF_ERR = (1 << 30), /* task file error */
-+ PORT_IRQ_HBUS_ERR = (1 << 29), /* host bus fatal error */
-+ PORT_IRQ_HBUS_DATA_ERR = (1 << 28), /* host bus data error */
-+ PORT_IRQ_IF_ERR = (1 << 27), /* interface fatal error */
-+ PORT_IRQ_IF_NONFATAL = (1 << 26), /* interface non-fatal error */
-+ PORT_IRQ_OVERFLOW = (1 << 24), /* xfer exhausted available S/G */
-+ PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */
-+
-+ PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */
-+ PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */
-+ PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */
-+ PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */
-+ PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */
-+ PORT_IRQ_SDB_FIS = (1 << 3), /* Set Device Bits FIS rx'd */
-+ PORT_IRQ_DMAS_FIS = (1 << 2), /* DMA Setup FIS rx'd */
-+ PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */
-+ PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */
-+
-+ PORT_IRQ_FATAL = PORT_IRQ_TF_ERR |
-+ PORT_IRQ_HBUS_ERR |
-+ PORT_IRQ_HBUS_DATA_ERR |
-+ PORT_IRQ_IF_ERR,
-+ DEF_PORT_IRQ = PORT_IRQ_FATAL | PORT_IRQ_PHYRDY |
-+ PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE |
-+ PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS |
-+ PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS |
-+ PORT_IRQ_D2H_REG_FIS,
-+
-+ /* PORT_CMD bits */
-+ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
-+ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
-+ PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
-+ PORT_CMD_POWER_ON = (1 << 2), /* Power up device */
-+ PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */
-+ PORT_CMD_START = (1 << 0), /* Enable port DMA engine */
-+
-+ PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
-+ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
-+ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
-+
-+ /* hpriv->flags bits */
-+ AHCI_FLAG_MSI = (1 << 0),
-+};
-+
-+struct ahci_cmd_hdr {
-+ u32 opts;
-+ u32 status;
-+ u32 tbl_addr;
-+ u32 tbl_addr_hi;
-+ u32 reserved[4];
-+};
-+
-+struct ahci_sg {
-+ u32 addr;
-+ u32 addr_hi;
-+ u32 reserved;
-+ u32 flags_size;
-+};
-+
-+struct ahci_host_priv {
-+ unsigned long flags;
-+ u32 cap; /* cache of HOST_CAP register */
-+ u32 port_map; /* cache of HOST_PORTS_IMPL reg */
-+};
-+
-+struct ahci_port_priv {
-+ struct ahci_cmd_hdr *cmd_slot;
-+ dma_addr_t cmd_slot_dma;
-+ void *cmd_tbl;
-+ dma_addr_t cmd_tbl_dma;
-+ struct ahci_sg *cmd_tbl_sg;
-+ void *rx_fis;
-+ dma_addr_t rx_fis_dma;
-+};
-+
-+static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
-+static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-+static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-+static int ahci_qc_issue(struct ata_queued_cmd *qc);
-+static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-+static void ahci_phy_reset(struct ata_port *ap);
-+static void ahci_irq_clear(struct ata_port *ap);
-+static void ahci_eng_timeout(struct ata_port *ap);
-+static int ahci_port_start(struct ata_port *ap);
-+static void ahci_port_stop(struct ata_port *ap);
-+static void ahci_host_stop(struct ata_host_set *host_set);
-+static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-+static void ahci_qc_prep(struct ata_queued_cmd *qc);
-+static u8 ahci_check_status(struct ata_port *ap);
-+static u8 ahci_check_err(struct ata_port *ap);
-+static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
-+static void ahci_remove_one (struct pci_dev *pdev);
-+
-+static Scsi_Host_Template ahci_sht = {
-+ .module = THIS_MODULE,
-+ .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
-+ .queuecommand = ata_scsi_queuecmd,
-+ .eh_strategy_handler = ata_scsi_error,
-+ .can_queue = ATA_DEF_QUEUE,
-+ .this_id = ATA_SHT_THIS_ID,
-+ .sg_tablesize = AHCI_MAX_SG,
-+ .max_sectors = ATA_MAX_SECTORS,
-+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
-+ .emulated = ATA_SHT_EMULATED,
-+ .use_clustering = AHCI_USE_CLUSTERING,
-+ .proc_name = DRV_NAME,
-+ .dma_boundary = AHCI_DMA_BOUNDARY,
-+ .slave_configure = ata_scsi_slave_config,
-+ .bios_param = ata_std_bios_param,
-+};
-+
-+static struct ata_port_operations ahci_ops = {
-+ .port_disable = ata_port_disable,
-+
-+ .check_status = ahci_check_status,
-+ .check_altstatus = ahci_check_status,
-+ .check_err = ahci_check_err,
-+ .dev_select = ata_noop_dev_select,
-+
-+ .tf_read = ahci_tf_read,
-+
-+ .phy_reset = ahci_phy_reset,
-+
-+ .qc_prep = ahci_qc_prep,
-+ .qc_issue = ahci_qc_issue,
-+
-+ .eng_timeout = ahci_eng_timeout,
-+
-+ .irq_handler = ahci_interrupt,
-+ .irq_clear = ahci_irq_clear,
-+
-+ .scr_read = ahci_scr_read,
-+ .scr_write = ahci_scr_write,
-+
-+ .port_start = ahci_port_start,
-+ .port_stop = ahci_port_stop,
-+ .host_stop = ahci_host_stop,
-+};
-+
-+static struct ata_port_info ahci_port_info[] = {
-+ /* board_ahci */
-+ {
-+ .sht = &ahci_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
-+ ATA_FLAG_PIO_DMA,
-+ .pio_mask = 0x03, /* pio3-4 */
-+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
-+ .port_ops = &ahci_ops,
-+ },
-+};
-+
-+static struct pci_device_id ahci_pci_tbl[] = {
-+ { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ICH6 */
-+ { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ICH6M */
-+ { PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ICH7 */
-+ { PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ICH7M */
-+ { PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ICH7R */
-+ { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ULi M5288 */
-+ { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ESB2 */
-+ { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ESB2 */
-+ { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ board_ahci }, /* ESB2 */
-+ { } /* terminate list */
-+};
-+
-+
-+static struct pci_driver ahci_pci_driver = {
-+ .name = DRV_NAME,
-+ .id_table = ahci_pci_tbl,
-+ .probe = ahci_init_one,
-+ .remove = ahci_remove_one,
-+};
-+
-+
-+static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
-+{
-+ return base + 0x100 + (port * 0x80);
-+}
-+
-+static inline void *ahci_port_base (void *base, unsigned int port)
-+{
-+ return (void *) ahci_port_base_ul((unsigned long)base, port);
-+}
-+
-+static void ahci_host_stop(struct ata_host_set *host_set)
-+{
-+ struct ahci_host_priv *hpriv = host_set->private_data;
-+ kfree(hpriv);
-+
-+ ata_host_stop(host_set);
-+}
-+
-+static int ahci_port_start(struct ata_port *ap)
-+{
-+ struct device *dev = ap->host_set->dev;
-+ struct ahci_host_priv *hpriv = ap->host_set->private_data;
-+ struct ahci_port_priv *pp;
-+ void *mem, *mmio = ap->host_set->mmio_base;
-+ void *port_mmio = ahci_port_base(mmio, ap->port_no);
-+ dma_addr_t mem_dma;
-+
-+ pp = kmalloc(sizeof(*pp), GFP_KERNEL);
-+ if (!pp)
-+ return -ENOMEM;
-+ memset(pp, 0, sizeof(*pp));
-+
-+ mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
-+ if (!mem) {
-+ kfree(pp);
-+ return -ENOMEM;
-+ }
-+ memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
-+
-+ /*
-+ * First item in chunk of DMA memory: 32-slot command table,
-+ * 32 bytes each in size
-+ */
-+ pp->cmd_slot = mem;
-+ pp->cmd_slot_dma = mem_dma;
-+
-+ mem += AHCI_CMD_SLOT_SZ;
-+ mem_dma += AHCI_CMD_SLOT_SZ;
-+
-+ /*
-+ * Second item: Received-FIS area
-+ */
-+ pp->rx_fis = mem;
-+ pp->rx_fis_dma = mem_dma;
-+
-+ mem += AHCI_RX_FIS_SZ;
-+ mem_dma += AHCI_RX_FIS_SZ;
-+
-+ /*
-+ * Third item: data area for storing a single command
-+ * and its scatter-gather table
-+ */
-+ pp->cmd_tbl = mem;
-+ pp->cmd_tbl_dma = mem_dma;
-+
-+ pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR;
-+
-+ ap->private_data = pp;
-+
-+ if (hpriv->cap & HOST_CAP_64)
-+ writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
-+ writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
-+ readl(port_mmio + PORT_LST_ADDR); /* flush */
-+
-+ if (hpriv->cap & HOST_CAP_64)
-+ writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
-+ writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
-+ readl(port_mmio + PORT_FIS_ADDR); /* flush */
-+
-+ writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
-+ PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
-+ PORT_CMD_START, port_mmio + PORT_CMD);
-+ readl(port_mmio + PORT_CMD); /* flush */
-+
-+ return 0;
-+}
-+
-+
-+static void ahci_port_stop(struct ata_port *ap)
-+{
-+ struct device *dev = ap->host_set->dev;
-+ struct ahci_port_priv *pp = ap->private_data;
-+ void *mmio = ap->host_set->mmio_base;
-+ void *port_mmio = ahci_port_base(mmio, ap->port_no);
-+ u32 tmp;
-+
-+ tmp = readl(port_mmio + PORT_CMD);
-+ tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
-+ writel(tmp, port_mmio + PORT_CMD);
-+ readl(port_mmio + PORT_CMD); /* flush */
-+
-+ /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
-+ * this is slightly incorrect.
-+ */
-+ msleep(500);
-+
-+ ap->private_data = NULL;
-+ dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
-+ pp->cmd_slot, pp->cmd_slot_dma);
-+ kfree(pp);
-+}
-+
-+static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
-+{
-+ unsigned int sc_reg;
-+
-+ switch (sc_reg_in) {
-+ case SCR_STATUS: sc_reg = 0; break;
-+ case SCR_CONTROL: sc_reg = 1; break;
-+ case SCR_ERROR: sc_reg = 2; break;
-+ case SCR_ACTIVE: sc_reg = 3; break;
-+ default:
-+ return 0xffffffffU;
-+ }
-+
-+ return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
-+}
-+
-+
-+static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
-+ u32 val)
-+{
-+ unsigned int sc_reg;
-+
-+ switch (sc_reg_in) {
-+ case SCR_STATUS: sc_reg = 0; break;
-+ case SCR_CONTROL: sc_reg = 1; break;
-+ case SCR_ERROR: sc_reg = 2; break;
-+ case SCR_ACTIVE: sc_reg = 3; break;
-+ default:
-+ return;
-+ }
-+
-+ writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
-+}
-+
-+static void ahci_phy_reset(struct ata_port *ap)
-+{
-+ void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-+ struct ata_taskfile tf;
-+ struct ata_device *dev = &ap->device[0];
-+ u32 tmp;
-+
-+ __sata_phy_reset(ap);
-+
-+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
-+ return;
-+
-+ tmp = readl(port_mmio + PORT_SIG);
-+ tf.lbah = (tmp >> 24) & 0xff;
-+ tf.lbam = (tmp >> 16) & 0xff;
-+ tf.lbal = (tmp >> 8) & 0xff;
-+ tf.nsect = (tmp) & 0xff;
-+
-+ dev->class = ata_dev_classify(&tf);
-+ if (!ata_dev_present(dev))
-+ ata_port_disable(ap);
-+}
-+
-+static u8 ahci_check_status(struct ata_port *ap)
-+{
-+ void *mmio = (void *) ap->ioaddr.cmd_addr;
-+
-+ return readl(mmio + PORT_TFDATA) & 0xFF;
-+}
-+
-+static u8 ahci_check_err(struct ata_port *ap)
-+{
-+ void *mmio = (void *) ap->ioaddr.cmd_addr;
-+
-+ return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
-+}
-+
-+static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ struct ahci_port_priv *pp = ap->private_data;
-+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
-+
-+ ata_tf_from_fis(d2h_fis, tf);
-+}
-+
-+static void ahci_fill_sg(struct ata_queued_cmd *qc)
-+{
-+ struct ahci_port_priv *pp = qc->ap->private_data;
-+ unsigned int i;
-+
-+ VPRINTK("ENTER\n");
-+
-+ /*
-+ * Next, the S/G list.
-+ */
-+ for (i = 0; i < qc->n_elem; i++) {
-+ u32 sg_len;
-+ dma_addr_t addr;
-+
-+ addr = sg_dma_address(&qc->sg[i]);
-+ sg_len = sg_dma_len(&qc->sg[i]);
-+
-+ pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff);
-+ pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
-+ pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1);
-+ }
-+}
-+
-+static void ahci_qc_prep(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ struct ahci_port_priv *pp = ap->private_data;
-+ u32 opts;
-+ const u32 cmd_fis_len = 5; /* five dwords */
-+
-+ /*
-+ * Fill in command slot information (currently only one slot,
-+ * slot 0, is currently since we don't do queueing)
-+ */
-+
-+ opts = (qc->n_elem << 16) | cmd_fis_len;
-+ if (qc->tf.flags & ATA_TFLAG_WRITE)
-+ opts |= AHCI_CMD_WRITE;
-+ if (is_atapi_taskfile(&qc->tf))
-+ opts |= AHCI_CMD_ATAPI;
-+
-+ pp->cmd_slot[0].opts = cpu_to_le32(opts);
-+ pp->cmd_slot[0].status = 0;
-+ pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
-+ pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
-+
-+ /*
-+ * Fill in command table information. First, the header,
-+ * a SATA Register - Host to Device command FIS.
-+ */
-+ ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
-+ if (opts & AHCI_CMD_ATAPI) {
-+ memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
-+ memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
-+ }
-+
-+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
-+ return;
-+
-+ ahci_fill_sg(qc);
-+}
-+
-+static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
-+{
-+ void *mmio = ap->host_set->mmio_base;
-+ void *port_mmio = ahci_port_base(mmio, ap->port_no);
-+ u32 tmp;
-+ int work;
-+
-+ /* stop DMA */
-+ tmp = readl(port_mmio + PORT_CMD);
-+ tmp &= ~PORT_CMD_START;
-+ writel(tmp, port_mmio + PORT_CMD);
-+
-+ /* wait for engine to stop. TODO: this could be
-+ * as long as 500 msec
-+ */
-+ work = 1000;
-+ while (work-- > 0) {
-+ tmp = readl(port_mmio + PORT_CMD);
-+ if ((tmp & PORT_CMD_LIST_ON) == 0)
-+ break;
-+ udelay(10);
-+ }
-+
-+ /* clear SATA phy error, if any */
-+ tmp = readl(port_mmio + PORT_SCR_ERR);
-+ writel(tmp, port_mmio + PORT_SCR_ERR);
-+
-+ /* if DRQ/BSY is set, device needs to be reset.
-+ * if so, issue COMRESET
-+ */
-+ tmp = readl(port_mmio + PORT_TFDATA);
-+ if (tmp & (ATA_BUSY | ATA_DRQ)) {
-+ writel(0x301, port_mmio + PORT_SCR_CTL);
-+ readl(port_mmio + PORT_SCR_CTL); /* flush */
-+ udelay(10);
-+ writel(0x300, port_mmio + PORT_SCR_CTL);
-+ readl(port_mmio + PORT_SCR_CTL); /* flush */
-+ }
-+
-+ /* re-start DMA */
-+ tmp = readl(port_mmio + PORT_CMD);
-+ tmp |= PORT_CMD_START;
-+ writel(tmp, port_mmio + PORT_CMD);
-+ readl(port_mmio + PORT_CMD); /* flush */
-+
-+ printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id);
-+}
-+
-+static void ahci_eng_timeout(struct ata_port *ap)
-+{
-+ void *mmio = ap->host_set->mmio_base;
-+ void *port_mmio = ahci_port_base(mmio, ap->port_no);
-+ struct ata_queued_cmd *qc;
-+
-+ DPRINTK("ENTER\n");
-+
-+ ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
-+
-+ qc = ata_qc_from_tag(ap, ap->active_tag);
-+ if (!qc) {
-+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-+ ap->id);
-+ } else {
-+ /* hack alert! We cannot use the supplied completion
-+ * function from inside the ->eh_strategy_handler() thread.
-+ * libata is the only user of ->eh_strategy_handler() in
-+ * any kernel, so the default scsi_done() assumes it is
-+ * not being called from the SCSI EH.
-+ */
-+ qc->scsidone = scsi_finish_command;
-+ ata_qc_complete(qc, ATA_ERR);
-+ }
-+
-+}
-+
-+static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
-+{
-+ void *mmio = ap->host_set->mmio_base;
-+ void *port_mmio = ahci_port_base(mmio, ap->port_no);
-+ u32 status, serr, ci;
-+
-+ serr = readl(port_mmio + PORT_SCR_ERR);
-+ writel(serr, port_mmio + PORT_SCR_ERR);
-+
-+ status = readl(port_mmio + PORT_IRQ_STAT);
-+ writel(status, port_mmio + PORT_IRQ_STAT);
-+
-+ ci = readl(port_mmio + PORT_CMD_ISSUE);
-+ if (likely((ci & 0x1) == 0)) {
-+ if (qc) {
-+ ata_qc_complete(qc, 0);
-+ qc = NULL;
-+ }
-+ }
-+
-+ if (status & PORT_IRQ_FATAL) {
-+ ahci_intr_error(ap, status);
-+ if (qc)
-+ ata_qc_complete(qc, ATA_ERR);
-+ }
-+
-+ return 1;
-+}
-+
-+static void ahci_irq_clear(struct ata_port *ap)
-+{
-+ /* TODO */
-+}
-+
-+static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
-+{
-+ struct ata_host_set *host_set = dev_instance;
-+ struct ahci_host_priv *hpriv;
-+ unsigned int i, handled = 0;
-+ void *mmio;
-+ u32 irq_stat, irq_ack = 0;
-+
-+ VPRINTK("ENTER\n");
-+
-+ hpriv = host_set->private_data;
-+ mmio = host_set->mmio_base;
-+
-+ /* sigh. 0xffffffff is a valid return from h/w */
-+ irq_stat = readl(mmio + HOST_IRQ_STAT);
-+ irq_stat &= hpriv->port_map;
-+ if (!irq_stat)
-+ return IRQ_NONE;
-+
-+ spin_lock(&host_set->lock);
-+
-+ for (i = 0; i < host_set->n_ports; i++) {
-+ struct ata_port *ap;
-+ u32 tmp;
-+
-+ VPRINTK("port %u\n", i);
-+ ap = host_set->ports[i];
-+ tmp = irq_stat & (1 << i);
-+ if (tmp && ap) {
-+ struct ata_queued_cmd *qc;
-+ qc = ata_qc_from_tag(ap, ap->active_tag);
-+ if (ahci_host_intr(ap, qc))
-+ irq_ack |= (1 << i);
-+ }
-+ }
-+
-+ if (irq_ack) {
-+ writel(irq_ack, mmio + HOST_IRQ_STAT);
-+ handled = 1;
-+ }
-+
-+ spin_unlock(&host_set->lock);
-+
-+ VPRINTK("EXIT\n");
-+
-+ return IRQ_RETVAL(handled);
-+}
-+
-+static int ahci_qc_issue(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ void *port_mmio = (void *) ap->ioaddr.cmd_addr;
-+
-+ writel(1, port_mmio + PORT_SCR_ACT);
-+ readl(port_mmio + PORT_SCR_ACT); /* flush */
-+
-+ writel(1, port_mmio + PORT_CMD_ISSUE);
-+ readl(port_mmio + PORT_CMD_ISSUE); /* flush */
-+
-+ return 0;
-+}
-+
-+static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
-+ unsigned int port_idx)
-+{
-+ VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
-+ base = ahci_port_base_ul(base, port_idx);
-+ VPRINTK("base now==0x%lx\n", base);
-+
-+ port->cmd_addr = base;
-+ port->scr_addr = base + PORT_SCR;
-+
-+ VPRINTK("EXIT\n");
-+}
-+
-+static int ahci_host_init(struct ata_probe_ent *probe_ent)
-+{
-+ struct ahci_host_priv *hpriv = probe_ent->private_data;
-+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-+ void __iomem *mmio = probe_ent->mmio_base;
-+ u32 tmp, cap_save;
-+ u16 tmp16;
-+ unsigned int i, j, using_dac;
-+ int rc;
-+ void __iomem *port_mmio;
-+
-+ cap_save = readl(mmio + HOST_CAP);
-+ cap_save &= ( (1<<28) | (1<<17) );
-+ cap_save |= (1 << 27);
-+
-+ /* global controller reset */
-+ tmp = readl(mmio + HOST_CTL);
-+ if ((tmp & HOST_RESET) == 0) {
-+ writel(tmp | HOST_RESET, mmio + HOST_CTL);
-+ readl(mmio + HOST_CTL); /* flush */
-+ }
-+
-+ /* reset must complete within 1 second, or
-+ * the hardware should be considered fried.
-+ */
-+ ssleep(1);
-+
-+ tmp = readl(mmio + HOST_CTL);
-+ if (tmp & HOST_RESET) {
-+ printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
-+ pci_name(pdev), tmp);
-+ return -EIO;
-+ }
-+
-+ writel(HOST_AHCI_EN, mmio + HOST_CTL);
-+ (void) readl(mmio + HOST_CTL); /* flush */
-+ writel(cap_save, mmio + HOST_CAP);
-+ writel(0xf, mmio + HOST_PORTS_IMPL);
-+ (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
-+
-+ pci_read_config_word(pdev, 0x92, &tmp16);
-+ tmp16 |= 0xf;
-+ pci_write_config_word(pdev, 0x92, tmp16);
-+
-+ hpriv->cap = readl(mmio + HOST_CAP);
-+ hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
-+ probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
-+
-+ VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
-+ hpriv->cap, hpriv->port_map, probe_ent->n_ports);
-+
-+ using_dac = hpriv->cap & HOST_CAP_64;
-+ if (using_dac &&
-+ !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-+ rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-+ if (rc) {
-+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-+ if (rc) {
-+ printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
-+ pci_name(pdev));
-+ return rc;
-+ }
-+ }
-+ } else {
-+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-+ if (rc) {
-+ printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
-+ pci_name(pdev));
-+ return rc;
-+ }
-+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-+ if (rc) {
-+ printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
-+ pci_name(pdev));
-+ return rc;
-+ }
-+ }
-+
-+ for (i = 0; i < probe_ent->n_ports; i++) {
-+#if 0 /* BIOSen initialize this incorrectly */
-+ if (!(hpriv->port_map & (1 << i)))
-+ continue;
-+#endif
-+
-+ port_mmio = ahci_port_base(mmio, i);
-+ VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio);
-+
-+ ahci_setup_port(&probe_ent->port[i],
-+ (unsigned long) mmio, i);
-+
-+ /* make sure port is not active */
-+ tmp = readl(port_mmio + PORT_CMD);
-+ VPRINTK("PORT_CMD 0x%x\n", tmp);
-+ if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-+ PORT_CMD_FIS_RX | PORT_CMD_START)) {
-+ tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-+ PORT_CMD_FIS_RX | PORT_CMD_START);
-+ writel(tmp, port_mmio + PORT_CMD);
-+ readl(port_mmio + PORT_CMD); /* flush */
-+
-+ /* spec says 500 msecs for each bit, so
-+ * this is slightly incorrect.
-+ */
-+ msleep(500);
-+ }
-+
-+ writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
-+
-+ j = 0;
-+ while (j < 100) {
-+ msleep(10);
-+ tmp = readl(port_mmio + PORT_SCR_STAT);
-+ if ((tmp & 0xf) == 0x3)
-+ break;
-+ j++;
-+ }
-+
-+ tmp = readl(port_mmio + PORT_SCR_ERR);
-+ VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
-+ writel(tmp, port_mmio + PORT_SCR_ERR);
-+
-+ /* ack any pending irq events for this port */
-+ tmp = readl(port_mmio + PORT_IRQ_STAT);
-+ VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
-+ if (tmp)
-+ writel(tmp, port_mmio + PORT_IRQ_STAT);
-+
-+ writel(1 << i, mmio + HOST_IRQ_STAT);
-+
-+ /* set irq mask (enables interrupts) */
-+ writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
-+ }
-+
-+ tmp = readl(mmio + HOST_CTL);
-+ VPRINTK("HOST_CTL 0x%x\n", tmp);
-+ writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
-+ tmp = readl(mmio + HOST_CTL);
-+ VPRINTK("HOST_CTL 0x%x\n", tmp);
-+
-+ pci_set_master(pdev);
-+
-+ return 0;
-+}
-+
-+/* move to PCI layer, integrate w/ MSI stuff */
-+static void pci_intx(struct pci_dev *pdev, int enable)
-+{
-+ u16 pci_command, new;
-+
-+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-+
-+ if (enable)
-+ new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
-+ else
-+ new = pci_command | PCI_COMMAND_INTX_DISABLE;
-+
-+ if (new != pci_command)
-+ pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-+}
-+
-+static void ahci_print_info(struct ata_probe_ent *probe_ent)
-+{
-+ struct ahci_host_priv *hpriv = probe_ent->private_data;
-+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-+ void *mmio = probe_ent->mmio_base;
-+ u32 vers, cap, impl, speed;
-+ const char *speed_s;
-+ u16 cc;
-+ const char *scc_s;
-+
-+ vers = readl(mmio + HOST_VERSION);
-+ cap = hpriv->cap;
-+ impl = hpriv->port_map;
-+
-+ speed = (cap >> 20) & 0xf;
-+ if (speed == 1)
-+ speed_s = "1.5";
-+ else if (speed == 2)
-+ speed_s = "3";
-+ else
-+ speed_s = "?";
-+
-+ pci_read_config_word(pdev, 0x0a, &cc);
-+ if (cc == 0x0101)
-+ scc_s = "IDE";
-+ else if (cc == 0x0106)
-+ scc_s = "SATA";
-+ else if (cc == 0x0104)
-+ scc_s = "RAID";
-+ else
-+ scc_s = "unknown";
-+
-+ printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
-+ "%u slots %u ports %s Gbps 0x%x impl %s mode\n"
-+ ,
-+ pci_name(pdev),
-+
-+ (vers >> 24) & 0xff,
-+ (vers >> 16) & 0xff,
-+ (vers >> 8) & 0xff,
-+ vers & 0xff,
-+
-+ ((cap >> 8) & 0x1f) + 1,
-+ (cap & 0x1f) + 1,
-+ speed_s,
-+ impl,
-+ scc_s);
-+
-+ printk(KERN_INFO DRV_NAME "(%s) flags: "
-+ "%s%s%s%s%s%s"
-+ "%s%s%s%s%s%s%s\n"
-+ ,
-+ pci_name(pdev),
-+
-+ cap & (1 << 31) ? "64bit " : "",
-+ cap & (1 << 30) ? "ncq " : "",
-+ cap & (1 << 28) ? "ilck " : "",
-+ cap & (1 << 27) ? "stag " : "",
-+ cap & (1 << 26) ? "pm " : "",
-+ cap & (1 << 25) ? "led " : "",
-+
-+ cap & (1 << 24) ? "clo " : "",
-+ cap & (1 << 19) ? "nz " : "",
-+ cap & (1 << 18) ? "only " : "",
-+ cap & (1 << 17) ? "pmp " : "",
-+ cap & (1 << 15) ? "pio " : "",
-+ cap & (1 << 14) ? "slum " : "",
-+ cap & (1 << 13) ? "part " : ""
-+ );
-+}
-+
-+static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-+{
-+ static int printed_version;
-+ struct ata_probe_ent *probe_ent = NULL;
-+ struct ahci_host_priv *hpriv;
-+ unsigned long base;
-+ void *mmio_base;
-+ unsigned int board_idx = (unsigned int) ent->driver_data;
-+ int have_msi, pci_dev_busy = 0;
-+ int rc;
-+
-+ VPRINTK("ENTER\n");
-+
-+ if (!printed_version++)
-+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
-+
-+ rc = pci_enable_device(pdev);
-+ if (rc)
-+ return rc;
-+
-+ rc = pci_request_regions(pdev, DRV_NAME);
-+ if (rc) {
-+ pci_dev_busy = 1;
-+ goto err_out;
-+ }
-+
-+ if (pci_enable_msi(pdev) == 0)
-+ have_msi = 1;
-+ else {
-+ pci_intx(pdev, 1);
-+ have_msi = 0;
-+ }
-+
-+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
-+ if (probe_ent == NULL) {
-+ rc = -ENOMEM;
-+ goto err_out_msi;
-+ }
-+
-+ memset(probe_ent, 0, sizeof(*probe_ent));
-+ probe_ent->dev = pci_dev_to_dev(pdev);
-+ INIT_LIST_HEAD(&probe_ent->node);
-+
-+ mmio_base = ioremap(pci_resource_start(pdev, AHCI_PCI_BAR),
-+ pci_resource_len(pdev, AHCI_PCI_BAR));
-+ if (mmio_base == NULL) {
-+ rc = -ENOMEM;
-+ goto err_out_free_ent;
-+ }
-+ base = (unsigned long) mmio_base;
-+
-+ hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
-+ if (!hpriv) {
-+ rc = -ENOMEM;
-+ goto err_out_iounmap;
-+ }
-+ memset(hpriv, 0, sizeof(*hpriv));
-+
-+ probe_ent->sht = ahci_port_info[board_idx].sht;
-+ probe_ent->host_flags = ahci_port_info[board_idx].host_flags;
-+ probe_ent->pio_mask = ahci_port_info[board_idx].pio_mask;
-+ probe_ent->udma_mask = ahci_port_info[board_idx].udma_mask;
-+ probe_ent->port_ops = ahci_port_info[board_idx].port_ops;
-+
-+ probe_ent->irq = pdev->irq;
-+ probe_ent->irq_flags = SA_SHIRQ;
-+ probe_ent->mmio_base = mmio_base;
-+ probe_ent->private_data = hpriv;
-+
-+ if (have_msi)
-+ hpriv->flags |= AHCI_FLAG_MSI;
-+
-+ /* initialize adapter */
-+ rc = ahci_host_init(probe_ent);
-+ if (rc)
-+ goto err_out_hpriv;
-+
-+ ahci_print_info(probe_ent);
-+
-+ /* FIXME: check ata_device_add return value */
-+ ata_device_add(probe_ent);
-+ kfree(probe_ent);
-+
-+ return 0;
-+
-+err_out_hpriv:
-+ kfree(hpriv);
-+err_out_iounmap:
-+ iounmap(mmio_base);
-+err_out_free_ent:
-+ kfree(probe_ent);
-+err_out_msi:
-+ if (have_msi)
-+ pci_disable_msi(pdev);
-+ else
-+ pci_intx(pdev, 0);
-+ pci_release_regions(pdev);
-+err_out:
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
-+ return rc;
-+}
-+
-+static void ahci_remove_one (struct pci_dev *pdev)
-+{
-+ struct device *dev = pci_dev_to_dev(pdev);
-+ struct ata_host_set *host_set = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host_set->private_data;
-+ struct ata_port *ap;
-+ unsigned int i;
-+ int have_msi;
-+
-+ for (i = 0; i < host_set->n_ports; i++) {
-+ ap = host_set->ports[i];
-+
-+ scsi_remove_host(ap->host);
-+ }
-+
-+ have_msi = hpriv->flags & AHCI_FLAG_MSI;
-+ free_irq(host_set->irq, host_set);
-+
-+ for (i = 0; i < host_set->n_ports; i++) {
-+ ap = host_set->ports[i];
-+
-+ ata_scsi_release(ap->host);
-+ scsi_host_put(ap->host);
-+ }
-+
-+ host_set->ops->host_stop(host_set);
-+ kfree(host_set);
-+
-+ if (have_msi)
-+ pci_disable_msi(pdev);
-+ else
-+ pci_intx(pdev, 0);
-+ pci_release_regions(pdev);
-+ pci_disable_device(pdev);
-+ dev_set_drvdata(dev, NULL);
-+}
-+
-+static int __init ahci_init(void)
-+{
-+ return pci_module_init(&ahci_pci_driver);
-+}
-+
-+
-+static void __exit ahci_exit(void)
-+{
-+ pci_unregister_driver(&ahci_pci_driver);
-+}
-+
-+
-+MODULE_AUTHOR("Jeff Garzik");
-+MODULE_DESCRIPTION("AHCI SATA low-level driver");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-+
-+module_init(ahci_init);
-+module_exit(ahci_exit);
---- ./drivers/scsi/sata_uli.c.libata 1970-01-01 03:00:00.000000000 +0300
-+++ ./drivers/scsi/sata_uli.c 2005-10-19 11:47:14.000000000 +0400
-@@ -0,0 +1,287 @@
-+/*
-+ * sata_uli.c - ULi Electronics SATA
-+ *
-+ * The contents of this file are subject to the Open
-+ * Software License version 1.1 that can be found at
-+ * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
-+ * by reference.
-+ *
-+ * Alternatively, the contents of this file may be used under the terms
-+ * of the GNU General Public License version 2 (the "GPL") as distributed
-+ * in the kernel source COPYING file, in which case the provisions of
-+ * the GPL are applicable instead of the above. If you wish to allow
-+ * the use of your version of this file only under the terms of the
-+ * GPL and not to allow others to use your version of this file under
-+ * the OSL, indicate your decision by deleting the provisions above and
-+ * replace them with the notice and other provisions required by the GPL.
-+ * If you do not delete the provisions above, a recipient may use your
-+ * version of this file under either the OSL or the GPL.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include "scsi.h"
-+#include <scsi/scsi_host.h>
-+#include <linux/libata.h>
-+
-+#define DRV_NAME "sata_uli"
-+#define DRV_VERSION "0.5"
-+
-+enum {
-+ uli_5289 = 0,
-+ uli_5287 = 1,
-+ uli_5281 = 2,
-+
-+ /* PCI configuration registers */
-+ ULI5287_BASE = 0x90, /* sata0 phy SCR registers */
-+ ULI5287_OFFS = 0x10, /* offset from sata0->sata1 phy regs */
-+ ULI5281_BASE = 0x60, /* sata0 phy SCR registers */
-+ ULI5281_OFFS = 0x60, /* offset from sata0->sata1 phy regs */
-+};
-+
-+static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-+static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
-+static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-+
-+static struct pci_device_id uli_pci_tbl[] = {
-+ { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
-+ { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
-+ { PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
-+ { } /* terminate list */
-+};
-+
-+
-+static struct pci_driver uli_pci_driver = {
-+ .name = DRV_NAME,
-+ .id_table = uli_pci_tbl,
-+ .probe = uli_init_one,
-+ .remove = ata_pci_remove_one,
-+};
-+
-+static Scsi_Host_Template uli_sht = {
-+ .module = THIS_MODULE,
-+ .name = DRV_NAME,
-+ .ioctl = ata_scsi_ioctl,
-+ .queuecommand = ata_scsi_queuecmd,
-+ .eh_strategy_handler = ata_scsi_error,
-+ .can_queue = ATA_DEF_QUEUE,
-+ .this_id = ATA_SHT_THIS_ID,
-+ .sg_tablesize = LIBATA_MAX_PRD,
-+ .max_sectors = ATA_MAX_SECTORS,
-+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
-+ .emulated = ATA_SHT_EMULATED,
-+ .use_clustering = ATA_SHT_USE_CLUSTERING,
-+ .proc_name = DRV_NAME,
-+ .dma_boundary = ATA_DMA_BOUNDARY,
-+ .slave_configure = ata_scsi_slave_config,
-+ .bios_param = ata_std_bios_param,
-+};
-+
-+static struct ata_port_operations uli_ops = {
-+ .port_disable = ata_port_disable,
-+
-+ .tf_load = ata_tf_load,
-+ .tf_read = ata_tf_read,
-+ .check_status = ata_check_status,
-+ .exec_command = ata_exec_command,
-+ .dev_select = ata_std_dev_select,
-+
-+ .phy_reset = sata_phy_reset,
-+
-+ .bmdma_setup = ata_bmdma_setup,
-+ .bmdma_start = ata_bmdma_start,
-+ .bmdma_stop = ata_bmdma_stop,
-+ .bmdma_status = ata_bmdma_status,
-+ .qc_prep = ata_qc_prep,
-+ .qc_issue = ata_qc_issue_prot,
-+
-+ .eng_timeout = ata_eng_timeout,
-+
-+ .irq_handler = ata_interrupt,
-+ .irq_clear = ata_bmdma_irq_clear,
-+
-+ .scr_read = uli_scr_read,
-+ .scr_write = uli_scr_write,
-+
-+ .port_start = ata_port_start,
-+ .port_stop = ata_port_stop,
-+ .host_stop = ata_host_stop,
-+};
-+
-+static struct ata_port_info uli_port_info = {
-+ .sht = &uli_sht,
-+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
-+ ATA_FLAG_NO_LEGACY,
-+ .pio_mask = 0x03, //support pio mode 4 (FIXME)
-+ .udma_mask = 0x7f, //support udma mode 6
-+ .port_ops = &uli_ops,
-+};
-+
-+
-+MODULE_AUTHOR("Peer Chen");
-+MODULE_DESCRIPTION("low-level driver for ULi Electronics SATA controller");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
-+MODULE_VERSION(DRV_VERSION);
-+
-+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
-+{
-+ return ap->ioaddr.scr_addr + (4 * sc_reg);
-+}
-+
-+static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
-+{
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-+ unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
-+ u32 val;
-+
-+ pci_read_config_dword(pdev, cfg_addr, &val);
-+ return val;
-+}
-+
-+static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
-+{
-+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-+ unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
-+
-+ pci_write_config_dword(pdev, cfg_addr, val);
-+}
-+
-+static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg)
-+{
-+ if (sc_reg > SCR_CONTROL)
-+ return 0xffffffffU;
-+
-+ return uli_scr_cfg_read(ap, sc_reg);
-+}
-+
-+static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
-+{
-+ if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
-+ return;
-+
-+ uli_scr_cfg_write(ap, sc_reg, val);
-+}
-+
-+/* move to PCI layer, integrate w/ MSI stuff */
-+static void pci_enable_intx(struct pci_dev *pdev)
-+{
-+ u16 pci_command;
-+
-+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-+ if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-+ pci_command &= ~PCI_COMMAND_INTX_DISABLE;
-+ pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-+ }
-+}
-+
-+static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-+{
-+ struct ata_probe_ent *probe_ent;
-+ struct ata_port_info *ppi;
-+ int rc;
-+ unsigned int board_idx = (unsigned int) ent->driver_data;
-+ int pci_dev_busy = 0;
-+
-+ rc = pci_enable_device(pdev);
-+ if (rc)
-+ return rc;
-+
-+ rc = pci_request_regions(pdev, DRV_NAME);
-+ if (rc) {
-+ pci_dev_busy = 1;
-+ goto err_out;
-+ }
-+
-+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-+ if (rc)
-+ goto err_out_regions;
-+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-+ if (rc)
-+ goto err_out_regions;
-+
-+ ppi = &uli_port_info;
-+ probe_ent = ata_pci_init_native_mode(pdev, &ppi);
-+ if (!probe_ent) {
-+ rc = -ENOMEM;
-+ goto err_out_regions;
-+ }
-+
-+ switch (board_idx) {
-+ case uli_5287:
-+ probe_ent->port[0].scr_addr = ULI5287_BASE;
-+ probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
-+ probe_ent->n_ports = 4;
-+
-+ probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
-+ probe_ent->port[2].altstatus_addr =
-+ probe_ent->port[2].ctl_addr =
-+ (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
-+ probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
-+ probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
-+
-+ probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
-+ probe_ent->port[3].altstatus_addr =
-+ probe_ent->port[3].ctl_addr =
-+ (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
-+ probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
-+ probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
-+
-+ ata_std_ports(&probe_ent->port[2]);
-+ ata_std_ports(&probe_ent->port[3]);
-+ break;
-+
-+ case uli_5289:
-+ probe_ent->port[0].scr_addr = ULI5287_BASE;
-+ probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
-+ break;
-+
-+ case uli_5281:
-+ probe_ent->port[0].scr_addr = ULI5281_BASE;
-+ probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
-+ break;
-+
-+ default:
-+ BUG();
-+ break;
-+ }
-+
-+ pci_set_master(pdev);
-+ pci_enable_intx(pdev);
-+
-+ /* FIXME: check ata_device_add return value */
-+ ata_device_add(probe_ent);
-+ kfree(probe_ent);
-+
-+ return 0;
-+
-+err_out_regions:
-+ pci_release_regions(pdev);
-+
-+err_out:
-+ if (!pci_dev_busy)
-+ pci_disable_device(pdev);
-+ return rc;
-+
-+}
-+
-+static int __init uli_init(void)
-+{
-+ return pci_module_init(&uli_pci_driver);
-+}
-+
-+static void __exit uli_exit(void)
-+{
-+ pci_unregister_driver(&uli_pci_driver);
-+}
-+
-+
-+module_init(uli_init);
-+module_exit(uli_exit);
---- ./drivers/scsi/Kconfig.libata 2004-08-14 14:56:14.000000000 +0400
-+++ ./drivers/scsi/Kconfig 2005-11-14 17:09:10.305251880 +0300
-@@ -414,6 +414,14 @@ config SCSI_SATA
-
- If unsure, say N.
-
-+config SCSI_SATA_AHCI
-+ tristate "AHCI SATA support"
-+ depends on SCSI_SATA && PCI && EXPERIMENTAL
-+ help
-+ This option enables support for AHCI Serial ATA.
-+
-+ If unsure, say N.
-+
- config SCSI_SATA_SVW
- tristate "ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)"
- depends on SCSI_SATA && PCI && EXPERIMENTAL