bk://gkernel.bkbits.net/libata-2.6 jgarzik@pobox.com|ChangeSet|20050202085421|32212 jgarzik # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/02/03 12:14:36-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-libata # # drivers/pci/quirks.c # 2005/02/03 12:14:32-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/02/02 03:54:21-05:00 jgarzik@pobox.com # [libata sata_promise] support Promise SATAII TX2/TX4 cards # # Originally from Peter Smith, with testing and additional # contributions from Jens Axboe. # # drivers/scsi/sata_promise.c # 2005/02/02 03:54:15-05:00 jgarzik@pobox.com +10 -2 # [libata sata_promise] support Promise SATAII TX2/TX4 cards # # Originally from Peter Smith, with testing and additional # contributions from Jens Axboe. # # ChangeSet # 2005/02/01 22:24:59-05:00 albertcc@tw.ibm.com # [libata] SCSI-to-ATA translation fixes # # Fixes lesser-used READ VERIFY and READ_16/WRITE_16 translations. # # Changes: # #1. ata_scsi_rw_xlat(): # Fix incorrect SCSI to ATA translation for 16 bytes SCSI Read/Write commands. # # #2. Fix ata_scsi_verify_xlat(): # Fix incorrect tf->hob_lbax translation. # # Signed-off-by: Albert Lee # # drivers/scsi/libata-scsi.c # 2005/02/01 22:24:53-05:00 albertcc@tw.ibm.com +4 -4 # [libata] SCSI-to-ATA translation fixes # # Fixes lesser-used READ VERIFY and READ_16/WRITE_16 translations. # # ChangeSet # 2005/02/01 22:15:18-05:00 achew@nvidia.com # [PATCH] sata_nv: enable generic class support for future NVIDIA SATA # # This patch adds a new entry in the pci_device_id table that filters # by class code, in order to cause unlisted NVIDIA SATA controllers to # be probed. In the probe function, we determine whether the device is # a SATA or IDE controller by checking the device's bars (NVIDIA SATA # controllers will always have 6 bars). Bar5 I/O mapped vs. memory # mapped is now determined programmatically by looking at the resource # flags of the bar. # # Signed-off-by: Andrew Chew # Signed-off-by: Jeff Garzik # # drivers/scsi/sata_nv.c # 2005/01/20 17:39:17-05:00 achew@nvidia.com +34 -11 # [PATCH} sata_nv: enable generic class support for future NVIDIA SATA # # ChangeSet # 2005/02/01 22:00:11-05:00 jgarzik@pobox.com # [libata] Remove CDROM drive from PATA DMA blacklist # # Mirrors changeset from Bart to drivers/ide/* # # drivers/scsi/libata-core.c # 2005/02/01 22:00:05-05:00 jgarzik@pobox.com +0 -1 # [libata] Remove CDROM drive from PATA DMA blacklist # # Mirrors changeset from Bart to drivers/ide/* # # ChangeSet # 2005/01/27 20:11:35-08:00 akpm@bix.(none) # Merge bk://gkernel.bkbits.net/libata-2.6 # into bix.(none):/usr/src/bk-libata # # drivers/scsi/ahci.c # 2005/01/27 20:11:29-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/01/10 14:23:34-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-libata # # drivers/pci/quirks.c # 2005/01/10 14:23:30-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/01/08 20:52:09-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-libata # # drivers/scsi/ahci.c # 2005/01/08 20:52:04-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/pci/quirks.c # 2005/01/08 20:52:04-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/01/08 18:28:34-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-libata # # drivers/scsi/ahci.c # 2005/01/08 18:28:24-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/01/07 14:18:26-08:00 akpm@bix.(none) # Merge bk://gkernel.bkbits.net/libata-2.6 # into bix.(none):/usr/src/bk-libata # # drivers/pci/quirks.c # 2005/01/07 14:18:21-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2005/01/06 20:37:41-05:00 jgarzik@pobox.com # [libata] add DMA blacklist # # Blacklist devices that seem to have some problem with DMA. # # From drivers/ide/ide-dma.c blacklist. # # drivers/scsi/libata-core.c # 2005/01/06 20:37:35-05:00 jgarzik@pobox.com +88 -4 # [libata] add DMA blacklist # # Blacklist devices that seem to have some problem with DMA. # # From drivers/ide/ide-dma.c blacklist. # diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c 2005-02-03 17:57:28 -08:00 +++ b/drivers/scsi/libata-core.c 2005-02-03 17:57:28 -08:00 @@ -1700,6 +1700,69 @@ DPRINTK("EXIT\n"); } +static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev) +{ + printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n", + ap->id, dev->devno); +} + +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", + "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", + "SAMSUNG CD-ROM SN-124", + "ATAPI CD-ROM DRIVE 40X MAXIMUM", + "_NEC DV5800A", +}; + +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; + + 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; + } + + for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) + if (!strncmp(ata_dma_blacklist[i], s, len)) + return 1; + + return 0; +} + static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift) { struct ata_device *master, *slave; @@ -1712,17 +1775,37 @@ if (shift == ATA_SHIFT_UDMA) { mask = ap->udma_mask; - if (ata_dev_present(master)) + if (ata_dev_present(master)) { mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dev_present(slave)) + 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); + } + } } else if (shift == ATA_SHIFT_MWDMA) { mask = ap->mwdma_mask; - if (ata_dev_present(master)) + if (ata_dev_present(master)) { mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); - if (ata_dev_present(slave)) + 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); + } + } } else if (shift == ATA_SHIFT_PIO) { mask = ap->pio_mask; diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c --- a/drivers/scsi/libata-scsi.c 2005-02-03 17:57:28 -08:00 +++ b/drivers/scsi/libata-scsi.c 2005-02-03 17:57:28 -08:00 @@ -498,9 +498,9 @@ tf->nsect = n_sect & 0xff; - tf->hob_lbah = (sect >> 16) & 0xff; - tf->hob_lbam = (sect >> 8) & 0xff; - tf->hob_lbal = sect & 0xff; + tf->lbah = (sect >> 16) & 0xff; + tf->lbam = (sect >> 8) & 0xff; + tf->lbal = sect & 0xff; return 0; } @@ -600,7 +600,7 @@ return 1; /* stores LBA27:24 in lower 4 bits of device reg */ - tf->device |= scsicmd[2]; + tf->device |= scsicmd[6]; qc->nsect = scsicmd[13]; } diff -Nru a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c --- a/drivers/scsi/sata_nv.c 2005-02-03 17:57:28 -08:00 +++ b/drivers/scsi/sata_nv.c 2005-02-03 17:57:28 -08:00 @@ -20,6 +20,10 @@ * 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. @@ -44,7 +48,7 @@ #include #define DRV_NAME "sata_nv" -#define DRV_VERSION "0.5" +#define DRV_VERSION "0.6" #define NV_PORTS 2 #define NV_PIO_MASK 0x1f @@ -108,6 +112,7 @@ enum nv_host_type { + GENERIC, NFORCE2, NFORCE3, CK804 @@ -128,6 +133,9 @@ 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 */ }; @@ -136,7 +144,6 @@ 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); @@ -144,21 +151,24 @@ }; 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, @@ -168,6 +178,7 @@ struct nv_host { struct nv_host_desc *host_desc; + unsigned long host_flags; }; static struct pci_driver nv_pci_driver = { @@ -284,8 +295,8 @@ 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)); } @@ -298,8 +309,8 @@ 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)); } @@ -322,6 +333,14 @@ struct ata_port_info *ppi; struct ata_probe_ent *probe_ent; 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"); @@ -352,11 +371,15 @@ if (!host) goto err_out_free_ent; + memset(host, 0, sizeof(struct nv_host)); host->host_desc = &nv_device_tbl[ent->driver_data]; 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), @@ -395,7 +418,7 @@ return 0; err_out_iounmap: - if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) iounmap(probe_ent->mmio_base); err_out_free_host: kfree(host); diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c --- a/drivers/scsi/sata_promise.c 2005-02-03 17:57:28 -08:00 +++ b/drivers/scsi/sata_promise.c 2005-02-03 17:57:28 -08:00 @@ -156,10 +156,16 @@ board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3376, 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 }, + { } /* terminate list */ }; @@ -406,9 +412,11 @@ 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));