From 77c5fd19075d299fe820bb59bb21b0b113676e20 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 9 Jan 2011 17:48:20 -0500 Subject: [PATCH 1/9] pata_mpc52xx: inherit from ata_bmdma_port_ops pata_mpc52xx supports BMDMA but inherits ata_sff_port_ops which triggers BUG_ON() when a DMA command is issued. Fix it. Signed-off-by: Tejun Heo Reported-by: Roman Fietze Cc: Sergei Shtylyov Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/pata_mpc52xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 8cc536e49a0..d7d8026cde9 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -610,7 +610,7 @@ static struct scsi_host_template mpc52xx_ata_sht = { }; static struct ata_port_operations mpc52xx_ata_port_ops = { - .inherits = &ata_sff_port_ops, + .inherits = &ata_bmdma_port_ops, .sff_dev_select = mpc52xx_ata_dev_select, .set_piomode = mpc52xx_ata_set_piomode, .set_dmamode = mpc52xx_ata_set_dmamode, From bfdd7c58cf3392333bba161491a2ef0741b970ba Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 10 Jan 2011 21:34:27 +0300 Subject: [PATCH 2/9] pata_hpt{366|37x}: use pr_warning(...) instead of printk(KERN_WARNING ...) ... in hpt_dma_blacklisted(). Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt366.c | 6 +++--- drivers/ata/pata_hpt37x.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index d7e57db36bc..538ec38ba99 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.9" +#define DRV_VERSION "0.6.10" struct hpt_clock { u8 xfer_mode; @@ -160,8 +160,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, while (list[i] != NULL) { if (!strcmp(list[i], model_num)) { - printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", - modestr, list[i]); + pr_warning(DRV_NAME ": %s is not supported for %s.\n", + modestr, list[i]); return 1; } i++; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index efdd18bc866..a1f830eaa7c 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.18" +#define DRV_VERSION "0.6.19" struct hpt_clock { u8 xfer_speed; @@ -229,8 +229,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, while (list[i] != NULL) { if (!strcmp(list[i], model_num)) { - printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", - modestr, list[i]); + pr_warning(DRV_NAME ": %s is not supported for %s.\n", + modestr, list[i]); return 1; } i++; From 40d69ba029c8d5de51aaeb5358999266c482d00a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 10 Jan 2011 21:39:34 +0300 Subject: [PATCH 3/9] pata_hpt{37x|3x2n}: use pr_*(DRV_NAME ...) instead of printk(KERN_* ...) ... the same as the 'pata_hpt366' driver does. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 22 +++++++++++----------- drivers/ata/pata_hpt3x2n.c | 12 +++++------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index a1f830eaa7c..6003a34d614 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.19" +#define DRV_VERSION "0.6.20" struct hpt_clock { u8 xfer_speed; @@ -863,7 +863,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) chip_table = &hpt372; break; default: - printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype, " + pr_err(DRV_NAME ": Unknown HPT366 subtype, " "please report (%d).\n", rev); return -ENODEV; } @@ -906,8 +906,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) *ppi = &info_hpt374_fn1; break; default: - printk(KERN_ERR - "pata_hpt37x: PCI table is bogus, please report (%d).\n", + pr_err(DRV_NAME + ": PCI table is bogus, please report (%d).\n", dev->device); return -ENODEV; } @@ -957,8 +957,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) u8 sr; u32 total = 0; - printk(KERN_WARNING - "pata_hpt37x: BIOS has not set timing clocks.\n"); + pr_warning(DRV_NAME ": BIOS has not set timing clocks.\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -1014,7 +1013,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); + pr_err(DRV_NAME ": DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1022,8 +1021,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n", - MHz[clock_slot], MHz[dpll]); + pr_info(DRV_NAME ": bus clock %dMHz, using %dMHz DPLL.\n", + MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; /* @@ -1036,8 +1035,9 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ppi[0] = &info_hpt370_33; if (clock_slot < 2 && ppi[0] == &info_hpt370a) ppi[0] = &info_hpt370a_33; - printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n", - chip_table->name, MHz[clock_slot]); + + pr_info(DRV_NAME ": %s using %dMHz bus clock.\n", + chip_table->name, MHz[clock_slot]); } /* Now kick off ATA set up */ diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index d2239bbdb79..eca68caf5f4 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.13" +#define DRV_VERSION "0.3.14" enum { HPT_PCI_FAST = (1 << 31), @@ -418,7 +418,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) u16 sr; u32 total = 0; - printk(KERN_WARNING "pata_hpt3x2n: BIOS clock data not set.\n"); + pr_warning(DRV_NAME ": BIOS clock data not set.\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -528,8 +528,7 @@ hpt372n: ppi[0] = &info_hpt372n; break; default: - printk(KERN_ERR - "pata_hpt3x2n: PCI table is bogus please report (%d).\n", + pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n", dev->device); return -ENODEV; } @@ -579,12 +578,11 @@ hpt372n: pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n"); + pr_err(DRV_NAME ": DPLL did not stabilize!\n"); return -ENODEV; } - printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", - pci_mhz); + pr_info(DRV_NAME ": bus clock %dMHz, using 66MHz DPLL.\n", pci_mhz); /* * Set our private data up. We only need a few flags From 910f7bb164fa888ff925e337bf8fd479abb157f9 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 10 Jan 2011 22:31:13 +0300 Subject: [PATCH 4/9] pata_hpt37x: fold 'if' statement into 'switch' hpt37x_init_one() has a large *if* statement which should really be folded into the *switch* statement that currently constitutes its *else* branch, reducing one level of indentation... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 89 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 6003a34d614..29d8adc5273 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.20" +#define DRV_VERSION "0.6.21" struct hpt_clock { u8 xfer_speed; @@ -838,7 +838,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (rc) return rc; - if (dev->device == PCI_DEVICE_ID_TTI_HPT366) { + switch (dev->device) { + case PCI_DEVICE_ID_TTI_HPT366: /* May be a later chip in disguise. Check */ /* Older chips are in the HPT366 driver. Ignore them */ if (rev < 3) @@ -867,50 +868,46 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) "please report (%d).\n", rev); return -ENODEV; } - } else { - switch (dev->device) { - case PCI_DEVICE_ID_TTI_HPT372: - /* 372N if rev >= 2 */ - if (rev >= 2) - return -ENODEV; - ppi[0] = &info_hpt372; - chip_table = &hpt372a; - break; - case PCI_DEVICE_ID_TTI_HPT302: - /* 302N if rev > 1 */ - if (rev > 1) - return -ENODEV; - ppi[0] = &info_hpt302; - /* Check this */ - chip_table = &hpt302; - break; - case PCI_DEVICE_ID_TTI_HPT371: - if (rev > 1) - return -ENODEV; - ppi[0] = &info_hpt302; - chip_table = &hpt371; - /* - * Single channel device, master is not present - * but the BIOS (or us for non x86) must mark it - * absent - */ - pci_read_config_byte(dev, 0x50, &mcr1); - mcr1 &= ~0x04; - pci_write_config_byte(dev, 0x50, mcr1); - break; - case PCI_DEVICE_ID_TTI_HPT374: - chip_table = &hpt374; - if (!(PCI_FUNC(dev->devfn) & 1)) - *ppi = &info_hpt374_fn0; - else - *ppi = &info_hpt374_fn1; - break; - default: - pr_err(DRV_NAME - ": PCI table is bogus, please report (%d).\n", - dev->device); - return -ENODEV; - } + break; + case PCI_DEVICE_ID_TTI_HPT372: + /* 372N if rev >= 2 */ + if (rev >= 2) + return -ENODEV; + ppi[0] = &info_hpt372; + chip_table = &hpt372a; + break; + case PCI_DEVICE_ID_TTI_HPT302: + /* 302N if rev > 1 */ + if (rev > 1) + return -ENODEV; + ppi[0] = &info_hpt302; + /* Check this */ + chip_table = &hpt302; + break; + case PCI_DEVICE_ID_TTI_HPT371: + if (rev > 1) + return -ENODEV; + ppi[0] = &info_hpt302; + chip_table = &hpt371; + /* + * Single channel device, master is not present but the BIOS + * (or us for non x86) must mark it absent + */ + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); + break; + case PCI_DEVICE_ID_TTI_HPT374: + chip_table = &hpt374; + if (!(PCI_FUNC(dev->devfn) & 1)) + *ppi = &info_hpt374_fn0; + else + *ppi = &info_hpt374_fn1; + break; + default: + pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n", + dev->device); + return -ENODEV; } /* Ok so this is a chip we support */ From a4a461a6df6c0481d5a3d61660ed97f5b539cf16 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Mon, 10 Jan 2011 12:57:17 -0800 Subject: [PATCH 5/9] ahci: AHCI mode SATA patch for Intel DH89xxCC DeviceIDs This patch adds the AHCI-mode SATA DeviceID for the Intel DH89xxCC PCH. Signed-off-by: Seth Heasley Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 328826381a2..3a43b116783 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -260,6 +260,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ + { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, From defed5593149e65cd7b7eaa32ccbf2e795ea55f1 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 11 Jan 2011 21:01:23 +0300 Subject: [PATCH 6/9] pata_hpt37x: inherit prereset() method for HPT374 Commit ab81a505ae6be069be5b67acd7e1bab3cfb53968 (pata_hpt37x: unify ->pre_reset methods) neglected to remove the initializer for the prereset() method from 'hpt374_fn1_port_ops' (it's inherited from 'hpt372_port_ops' anyway), as well as to update the comment in hpt37x_init_one()... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 29d8adc5273..4c5b5183225 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.21" +#define DRV_VERSION "0.6.22" struct hpt_clock { u8 xfer_speed; @@ -642,7 +642,6 @@ static struct ata_port_operations hpt372_port_ops = { static struct ata_port_operations hpt374_fn1_port_ops = { .inherits = &hpt372_port_ops, .cable_detect = hpt374_fn1_cable_detect, - .prereset = hpt37x_pre_reset, }; /** @@ -803,7 +802,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = ATA_UDMA6, .port_ops = &hpt302_port_ops }; - /* HPT374 - UDMA100, function 1 uses different prereset method */ + /* HPT374 - UDMA100, function 1 uses different cable_detect method */ static const struct ata_port_info info_hpt374_fn0 = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, From 10aca06c82a85fe7dcb3d8ad1b0b66e8635c8b8b Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 18 Jan 2011 20:03:26 -0500 Subject: [PATCH 7/9] ahci: add HFLAG_YES_FBS and apply it to 88SE9128 Commit 5f173107ecad83a50 added HFLAG_YES_FBS workaround for 88SE9128 (1b4b:9123). However, that change inadvertently caused the legacy IDE interface of the controller (with the same pci id) to become associated with the AHCI driver as well, causing the driver to try to bring the interface up in vain. Fix that by matching against class as well. Signed-off-by: Anssi Hannula Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 3a43b116783..b8d96ce37fc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -380,6 +380,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ { PCI_DEVICE(0x1b4b, 0x9123), + .class = PCI_CLASS_STORAGE_SATA_AHCI, + .class_mask = 0xffffff, .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ /* Promise */ From 4a5610a04d415ed94af75bb1159d2621d62c8328 Mon Sep 17 00:00:00 2001 From: Francesco Antonacci Date: Tue, 25 Jan 2011 11:54:43 +0100 Subject: [PATCH 8/9] libata: DVR-212D can't do SETXFER DVD-RW DVR-212D PIONEER DVR-212D can't do SETXFER like its sibling DVRTD08. Add ATA_HORKAGE_NOSETXFER for it. Reported in bko#27502. https://bugzilla.kernel.org/show_bug.cgi?id=27502 Signed-off-by: Francesco Antonacci Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a31fe96f7de..d4e52e21485 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4138,6 +4138,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { * device and controller are SATA. */ { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, /* End Marker */ { } From 729a6a300e628a48cf12bac93a964a535e83cd1d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 20 Jan 2011 13:59:06 +0100 Subject: [PATCH 9/9] libata: set queue DMA alignment to sector size for ATAPI too ata_pio_sectors() expects buffer for each sector to be contained in a single page; otherwise, it ends up overrunning the first page. This is achieved by setting queue DMA alignment. If sector_size is smaller than PAGE_SIZE and all buffers are sector_size aligned, buffer for each sector is always contained in a single page. This wasn't applied to ATAPI devices but IDENTIFY_PACKET is executed as ATA_PROT_PIO and thus uses ata_pio_sectors(). Newer versions of udev issue IDENTIFY_PACKET with unaligned buffer triggering the problem and causing oops. This patch fixes the problem by setting sdev->sector_size to ATA_SECT_SIZE on ATATPI devices and always setting DMA alignment to sector_size. While at it, add a warning for the unlikely but still possible scenario where sector_size is larger than PAGE_SIZE, in which case the alignment wouldn't be enough. Signed-off-by: Tejun Heo Reported-by: John Stanley Tested-by: John Stanley Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 5defc74973d..600f6353ecf 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1099,9 +1099,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, struct request_queue *q = sdev->request_queue; void *buf; - /* set the min alignment and padding */ - blk_queue_update_dma_alignment(sdev->request_queue, - ATA_DMA_PAD_SZ - 1); + sdev->sector_size = ATA_SECT_SIZE; + + /* set DMA padding */ blk_queue_update_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); @@ -1115,13 +1115,25 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN); } else { - /* ATA devices must be sector aligned */ sdev->sector_size = ata_id_logical_sector_size(dev->id); - blk_queue_update_dma_alignment(sdev->request_queue, - sdev->sector_size - 1); sdev->manage_start_stop = 1; } + /* + * ata_pio_sectors() expects buffer for each sector to not cross + * page boundary. Enforce it by requiring buffers to be sector + * aligned, which works iff sector_size is not larger than + * PAGE_SIZE. ATAPI devices also need the alignment as + * IDENTIFY_PACKET is executed as ATA_PROT_PIO. + */ + if (sdev->sector_size > PAGE_SIZE) + ata_dev_printk(dev, KERN_WARNING, + "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", + sdev->sector_size); + + blk_queue_update_dma_alignment(sdev->request_queue, + sdev->sector_size - 1); + if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);