diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 39 | ||||
| -rw-r--r-- | drivers/ata/pata_hpt37x.c | 49 | ||||
| -rw-r--r-- | drivers/ata/pata_serverworks.c | 11 | ||||
| -rw-r--r-- | include/linux/ata.h | 11 | ||||
| -rw-r--r-- | include/linux/libata.h | 1 |
5 files changed, 83 insertions, 28 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 164c7d9514f9..ec3ce120a517 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -676,10 +676,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 676 | if (rc) | 676 | if (rc) |
| 677 | return rc; | 677 | return rc; |
| 678 | 678 | ||
| 679 | /* disable DIPM */ | 679 | /* |
| 680 | if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM)) | 680 | * we don't have to disable DIPM since IPM flags |
| 681 | err_mask = ata_dev_set_feature(dev, | 681 | * disallow transitions to SLUMBER, which effectively |
| 682 | SETFEATURES_SATA_DISABLE, SATA_DIPM); | 682 | * disable DIPM if it does not support PARTIAL |
| 683 | */ | ||
| 683 | break; | 684 | break; |
| 684 | case NOT_AVAILABLE: | 685 | case NOT_AVAILABLE: |
| 685 | case MAX_PERFORMANCE: | 686 | case MAX_PERFORMANCE: |
| @@ -689,10 +690,11 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 689 | if (rc) | 690 | if (rc) |
| 690 | return rc; | 691 | return rc; |
| 691 | 692 | ||
| 692 | /* disable DIPM */ | 693 | /* |
| 693 | if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM)) | 694 | * we don't have to disable DIPM since IPM flags |
| 694 | err_mask = ata_dev_set_feature(dev, | 695 | * disallow all transitions which effectively |
| 695 | SETFEATURES_SATA_DISABLE, SATA_DIPM); | 696 | * disable DIPM anyway. |
| 697 | */ | ||
| 696 | break; | 698 | break; |
| 697 | } | 699 | } |
| 698 | 700 | ||
| @@ -4239,6 +4241,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4239 | { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, }, | 4241 | { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, }, |
| 4240 | { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, }, | 4242 | { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, }, |
| 4241 | 4243 | ||
| 4244 | /* Devices which get the IVB wrong */ | ||
| 4245 | { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, }, | ||
| 4246 | { "TSSTcorp CDDVDW SH-S202J", "SB00", ATA_HORKAGE_IVB, }, | ||
| 4247 | |||
| 4242 | /* End Marker */ | 4248 | /* End Marker */ |
| 4243 | { } | 4249 | { } |
| 4244 | }; | 4250 | }; |
| @@ -4300,6 +4306,21 @@ static int ata_dma_blacklisted(const struct ata_device *dev) | |||
| 4300 | } | 4306 | } |
| 4301 | 4307 | ||
| 4302 | /** | 4308 | /** |
| 4309 | * ata_is_40wire - check drive side detection | ||
| 4310 | * @dev: device | ||
| 4311 | * | ||
| 4312 | * Perform drive side detection decoding, allowing for device vendors | ||
| 4313 | * who can't follow the documentation. | ||
| 4314 | */ | ||
| 4315 | |||
| 4316 | static int ata_is_40wire(struct ata_device *dev) | ||
| 4317 | { | ||
| 4318 | if (dev->horkage & ATA_HORKAGE_IVB) | ||
| 4319 | return ata_drive_40wire_relaxed(dev->id); | ||
| 4320 | return ata_drive_40wire(dev->id); | ||
| 4321 | } | ||
| 4322 | |||
| 4323 | /** | ||
| 4303 | * ata_dev_xfermask - Compute supported xfermask of the given device | 4324 | * ata_dev_xfermask - Compute supported xfermask of the given device |
| 4304 | * @dev: Device to compute xfermask for | 4325 | * @dev: Device to compute xfermask for |
| 4305 | * | 4326 | * |
| @@ -4368,7 +4389,7 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
| 4368 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) | 4389 | if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) |
| 4369 | /* UDMA/44 or higher would be available */ | 4390 | /* UDMA/44 or higher would be available */ |
| 4370 | if ((ap->cbl == ATA_CBL_PATA40) || | 4391 | if ((ap->cbl == ATA_CBL_PATA40) || |
| 4371 | (ata_drive_40wire(dev->id) && | 4392 | (ata_is_40wire(dev) && |
| 4372 | (ap->cbl == ATA_CBL_PATA_UNK || | 4393 | (ap->cbl == ATA_CBL_PATA_UNK || |
| 4373 | ap->cbl == ATA_CBL_PATA80))) { | 4394 | ap->cbl == ATA_CBL_PATA80))) { |
| 4374 | ata_dev_printk(dev, KERN_WARNING, | 4395 | ata_dev_printk(dev, KERN_WARNING, |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index e61cb1fd57b2..3816b8605e0d 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
| @@ -295,7 +295,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask) | |||
| 295 | 295 | ||
| 296 | static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) | 296 | static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) |
| 297 | { | 297 | { |
| 298 | if (adev->class != ATA_DEV_ATA) { | 298 | if (adev->class == ATA_DEV_ATA) { |
| 299 | if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) | 299 | if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) |
| 300 | mask &= ~ (0x1F << ATA_SHIFT_UDMA); | 300 | mask &= ~ (0x1F << ATA_SHIFT_UDMA); |
| 301 | } | 301 | } |
| @@ -359,28 +359,25 @@ static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline) | |||
| 359 | { 0x50, 1, 0x04, 0x04 }, | 359 | { 0x50, 1, 0x04, 0x04 }, |
| 360 | { 0x54, 1, 0x04, 0x04 } | 360 | { 0x54, 1, 0x04, 0x04 } |
| 361 | }; | 361 | }; |
| 362 | u16 mcr3, mcr6; | 362 | u16 mcr3; |
| 363 | u8 ata66; | 363 | u8 ata66; |
| 364 | struct ata_port *ap = link->ap; | 364 | struct ata_port *ap = link->ap; |
| 365 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 365 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
| 366 | unsigned int mcrbase = 0x50 + 4 * ap->port_no; | ||
| 366 | 367 | ||
| 367 | if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) | 368 | if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) |
| 368 | return -ENOENT; | 369 | return -ENOENT; |
| 369 | 370 | ||
| 370 | /* Do the extra channel work */ | 371 | /* Do the extra channel work */ |
| 371 | pci_read_config_word(pdev, 0x52, &mcr3); | 372 | pci_read_config_word(pdev, mcrbase + 2, &mcr3); |
| 372 | pci_read_config_word(pdev, 0x56, &mcr6); | ||
| 373 | /* Set bit 15 of 0x52 to enable TCBLID as input | 373 | /* Set bit 15 of 0x52 to enable TCBLID as input |
| 374 | Set bit 15 of 0x56 to enable FCBLID as input | ||
| 375 | */ | 374 | */ |
| 376 | pci_write_config_word(pdev, 0x52, mcr3 | 0x8000); | 375 | pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000); |
| 377 | pci_write_config_word(pdev, 0x56, mcr6 | 0x8000); | ||
| 378 | pci_read_config_byte(pdev, 0x5A, &ata66); | 376 | pci_read_config_byte(pdev, 0x5A, &ata66); |
| 379 | /* Reset TCBLID/FCBLID to output */ | 377 | /* Reset TCBLID/FCBLID to output */ |
| 380 | pci_write_config_word(pdev, 0x52, mcr3); | 378 | pci_write_config_word(pdev, 0x52, mcr3); |
| 381 | pci_write_config_word(pdev, 0x56, mcr6); | ||
| 382 | 379 | ||
| 383 | if (ata66 & (1 << ap->port_no)) | 380 | if (ata66 & (2 >> ap->port_no)) |
| 384 | ap->cbl = ATA_CBL_PATA40; | 381 | ap->cbl = ATA_CBL_PATA40; |
| 385 | else | 382 | else |
| 386 | ap->cbl = ATA_CBL_PATA80; | 383 | ap->cbl = ATA_CBL_PATA80; |
| @@ -844,6 +841,25 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) | |||
| 844 | /* Never went stable */ | 841 | /* Never went stable */ |
| 845 | return 0; | 842 | return 0; |
| 846 | } | 843 | } |
| 844 | |||
| 845 | static u32 hpt374_read_freq(struct pci_dev *pdev) | ||
| 846 | { | ||
| 847 | u32 freq; | ||
| 848 | unsigned long io_base = pci_resource_start(pdev, 4); | ||
| 849 | if (PCI_FUNC(pdev->devfn) & 1) { | ||
| 850 | struct pci_dev *pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1); | ||
| 851 | /* Someone hot plugged the controller on us ? */ | ||
| 852 | if (pdev_0 == NULL) | ||
| 853 | return 0; | ||
| 854 | io_base = pci_resource_start(pdev_0, 4); | ||
| 855 | freq = inl(io_base + 0x90); | ||
| 856 | pci_dev_put(pdev_0); | ||
| 857 | } | ||
| 858 | else | ||
| 859 | freq = inl(io_base + 0x90); | ||
| 860 | return freq; | ||
| 861 | } | ||
| 862 | |||
| 847 | /** | 863 | /** |
| 848 | * hpt37x_init_one - Initialise an HPT37X/302 | 864 | * hpt37x_init_one - Initialise an HPT37X/302 |
| 849 | * @dev: PCI device | 865 | * @dev: PCI device |
| @@ -902,7 +918,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 902 | .flags = ATA_FLAG_SLAVE_POSS, | 918 | .flags = ATA_FLAG_SLAVE_POSS, |
| 903 | .pio_mask = 0x1f, | 919 | .pio_mask = 0x1f, |
| 904 | .mwdma_mask = 0x07, | 920 | .mwdma_mask = 0x07, |
| 905 | .udma_mask = 0x0f, | 921 | .udma_mask = ATA_UDMA5, |
| 906 | .port_ops = &hpt370_port_ops | 922 | .port_ops = &hpt370_port_ops |
| 907 | }; | 923 | }; |
| 908 | /* HPT370A - UDMA100 */ | 924 | /* HPT370A - UDMA100 */ |
| @@ -911,7 +927,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 911 | .flags = ATA_FLAG_SLAVE_POSS, | 927 | .flags = ATA_FLAG_SLAVE_POSS, |
| 912 | .pio_mask = 0x1f, | 928 | .pio_mask = 0x1f, |
| 913 | .mwdma_mask = 0x07, | 929 | .mwdma_mask = 0x07, |
| 914 | .udma_mask = 0x0f, | 930 | .udma_mask = ATA_UDMA5, |
| 915 | .port_ops = &hpt370a_port_ops | 931 | .port_ops = &hpt370a_port_ops |
| 916 | }; | 932 | }; |
| 917 | /* HPT371, 372 and friends - UDMA133 */ | 933 | /* HPT371, 372 and friends - UDMA133 */ |
| @@ -1047,9 +1063,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1047 | outb(0x0e, iobase + 0x9c); | 1063 | outb(0x0e, iobase + 0x9c); |
| 1048 | 1064 | ||
| 1049 | /* Some devices do not let this value be accessed via PCI space | 1065 | /* Some devices do not let this value be accessed via PCI space |
| 1050 | according to the old driver */ | 1066 | according to the old driver. In addition we must use the value |
| 1067 | from FN 0 on the HPT374 */ | ||
| 1068 | |||
| 1069 | if (chip_table == &hpt374) { | ||
| 1070 | freq = hpt374_read_freq(dev); | ||
| 1071 | if (freq == 0) | ||
| 1072 | return -ENODEV; | ||
| 1073 | } else | ||
| 1074 | freq = inl(iobase + 0x90); | ||
| 1051 | 1075 | ||
| 1052 | freq = inl(iobase + 0x90); | ||
| 1053 | if ((freq >> 12) != 0xABCDE) { | 1076 | if ((freq >> 12) != 0xABCDE) { |
| 1054 | int i; | 1077 | int i; |
| 1055 | u8 sr; | 1078 | u8 sr; |
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index df68806df4be..8bed88873720 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c | |||
| @@ -274,28 +274,27 @@ static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev | |||
| 274 | { | 274 | { |
| 275 | static const u8 dma_mode[] = { 0x77, 0x21, 0x20 }; | 275 | static const u8 dma_mode[] = { 0x77, 0x21, 0x20 }; |
| 276 | int offset = 1 + 2 * ap->port_no - adev->devno; | 276 | int offset = 1 + 2 * ap->port_no - adev->devno; |
| 277 | int devbits = (2 * ap->port_no + adev->devno); | 277 | int devbits = 2 * ap->port_no + adev->devno; |
| 278 | u8 ultra; | 278 | u8 ultra; |
| 279 | u8 ultra_cfg; | 279 | u8 ultra_cfg; |
| 280 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 280 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
| 281 | 281 | ||
| 282 | pci_read_config_byte(pdev, 0x54, &ultra_cfg); | 282 | pci_read_config_byte(pdev, 0x54, &ultra_cfg); |
| 283 | pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra); | ||
| 284 | ultra &= ~(0x0F << (adev->devno * 4)); | ||
| 283 | 285 | ||
| 284 | if (adev->dma_mode >= XFER_UDMA_0) { | 286 | if (adev->dma_mode >= XFER_UDMA_0) { |
| 285 | pci_write_config_byte(pdev, 0x44 + offset, 0x20); | 287 | pci_write_config_byte(pdev, 0x44 + offset, 0x20); |
| 286 | 288 | ||
| 287 | pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra); | ||
| 288 | ultra &= ~(0x0F << (ap->port_no * 4)); | ||
| 289 | ultra |= (adev->dma_mode - XFER_UDMA_0) | 289 | ultra |= (adev->dma_mode - XFER_UDMA_0) |
| 290 | << (ap->port_no * 4); | 290 | << (adev->devno * 4); |
| 291 | pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra); | ||
| 292 | |||
| 293 | ultra_cfg |= (1 << devbits); | 291 | ultra_cfg |= (1 << devbits); |
| 294 | } else { | 292 | } else { |
| 295 | pci_write_config_byte(pdev, 0x44 + offset, | 293 | pci_write_config_byte(pdev, 0x44 + offset, |
| 296 | dma_mode[adev->dma_mode - XFER_MW_DMA_0]); | 294 | dma_mode[adev->dma_mode - XFER_MW_DMA_0]); |
| 297 | ultra_cfg &= ~(1 << devbits); | 295 | ultra_cfg &= ~(1 << devbits); |
| 298 | } | 296 | } |
| 297 | pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra); | ||
| 299 | pci_write_config_byte(pdev, 0x54, ultra_cfg); | 298 | pci_write_config_byte(pdev, 0x54, ultra_cfg); |
| 300 | } | 299 | } |
| 301 | 300 | ||
diff --git a/include/linux/ata.h b/include/linux/ata.h index 61535e72834d..5c4e54a2a8d6 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
| @@ -425,6 +425,8 @@ static inline int ata_id_has_lba48(const u16 *id) | |||
| 425 | { | 425 | { |
| 426 | if ((id[83] & 0xC000) != 0x4000) | 426 | if ((id[83] & 0xC000) != 0x4000) |
| 427 | return 0; | 427 | return 0; |
| 428 | if (!ata_id_u64(id, 100)) | ||
| 429 | return 0; | ||
| 428 | return id[83] & (1 << 10); | 430 | return id[83] & (1 << 10); |
| 429 | } | 431 | } |
| 430 | 432 | ||
| @@ -535,6 +537,15 @@ static inline int ata_drive_40wire(const u16 *dev_id) | |||
| 535 | return 1; | 537 | return 1; |
| 536 | } | 538 | } |
| 537 | 539 | ||
| 540 | static inline int ata_drive_40wire_relaxed(const u16 *dev_id) | ||
| 541 | { | ||
| 542 | if (ata_id_is_sata(dev_id)) | ||
| 543 | return 0; /* SATA */ | ||
| 544 | if ((dev_id[93] & 0x2000) == 0x2000) | ||
| 545 | return 0; /* 80 wire */ | ||
| 546 | return 1; | ||
| 547 | } | ||
| 548 | |||
| 538 | static inline int atapi_cdb_len(const u16 *dev_id) | 549 | static inline int atapi_cdb_len(const u16 *dev_id) |
| 539 | { | 550 | { |
| 540 | u16 tmp = dev_id[0] & 0x3; | 551 | u16 tmp = dev_id[0] & 0x3; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 1e277852ba42..56a5673aebad 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -339,6 +339,7 @@ enum { | |||
| 339 | ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ | 339 | ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ |
| 340 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ | 340 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ |
| 341 | ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ | 341 | ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ |
| 342 | ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ | ||
| 342 | 343 | ||
| 343 | /* DMA mask for user DMA control: User visible values; DO NOT | 344 | /* DMA mask for user DMA control: User visible values; DO NOT |
| 344 | renumber */ | 345 | renumber */ |
