From 1b9715bc80fe0852cf4c0a289fe849c3757490b9 Mon Sep 17 00:00:00 2001 From: Christian Heim Date: Sun, 5 Nov 2006 10:46:32 +0000 Subject: We are now using UPSTREAMs tarball svn path=/; revision=523 --- .../022.056/5101_linux-2.6.8.1-libata-1.11.patch | 9939 -------------------- 1 file changed, 9939 deletions(-) delete mode 100644 openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch (limited to 'openvz-sources/022.056/5101_linux-2.6.8.1-libata-1.11.patch') 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 - - #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 - #include - #include -+#include - #include "scsi.h" - #include - #include - - #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 -+#include -+#include -+#include -+#include "scsi.h" -+#include -+#include -+#include -+ -+#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, ®s); -+ 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 - #include - #include -+#include - #include - #include - #include -@@ -39,22 +40,27 @@ - #include - #include - #include "scsi.h" -+#include "scsi_priv.h" - #include - #include - #include - #include -+#include - - #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 "". - */ - --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 ""; -+ -+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 -+ * 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 - - #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 - - #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, ®val); -+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); - 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, ®val); -+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); - 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 -@@ -38,11 +43,14 @@ - #include - - #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 - - #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 - #include -+#include - - #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 - #include -+#include - #include - #include - #include -@@ -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 -+ - /* 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "scsi.h" -+#include -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "scsi.h" -+#include -+#include -+ -+#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 -- cgit v1.2.3-65-gdbad