diff options
Diffstat (limited to 'drivers/ata/pata_hpt366.c')
-rw-r--r-- | drivers/ata/pata_hpt366.c | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index c0e150a9586b..2663599a7c02 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/libata.h> | 27 | #include <linux/libata.h> |
28 | 28 | ||
29 | #define DRV_NAME "pata_hpt366" | 29 | #define DRV_NAME "pata_hpt366" |
30 | #define DRV_VERSION "0.5" | 30 | #define DRV_VERSION "0.5.3" |
31 | 31 | ||
32 | struct hpt_clock { | 32 | struct hpt_clock { |
33 | u8 xfer_speed; | 33 | u8 xfer_speed; |
@@ -222,9 +222,17 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed) | |||
222 | 222 | ||
223 | static int hpt36x_pre_reset(struct ata_port *ap) | 223 | static int hpt36x_pre_reset(struct ata_port *ap) |
224 | { | 224 | { |
225 | static const struct pci_bits hpt36x_enable_bits[] = { | ||
226 | { 0x50, 1, 0x04, 0x04 }, | ||
227 | { 0x54, 1, 0x04, 0x04 } | ||
228 | }; | ||
229 | |||
225 | u8 ata66; | 230 | u8 ata66; |
226 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 231 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
227 | 232 | ||
233 | if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no])) | ||
234 | return -ENOENT; | ||
235 | |||
228 | pci_read_config_byte(pdev, 0x5A, &ata66); | 236 | pci_read_config_byte(pdev, 0x5A, &ata66); |
229 | if (ata66 & (1 << ap->port_no)) | 237 | if (ata66 & (1 << ap->port_no)) |
230 | ap->cbl = ATA_CBL_PATA40; | 238 | ap->cbl = ATA_CBL_PATA40; |
@@ -322,7 +330,6 @@ static struct scsi_host_template hpt36x_sht = { | |||
322 | .can_queue = ATA_DEF_QUEUE, | 330 | .can_queue = ATA_DEF_QUEUE, |
323 | .this_id = ATA_SHT_THIS_ID, | 331 | .this_id = ATA_SHT_THIS_ID, |
324 | .sg_tablesize = LIBATA_MAX_PRD, | 332 | .sg_tablesize = LIBATA_MAX_PRD, |
325 | .max_sectors = ATA_MAX_SECTORS, | ||
326 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 333 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
327 | .emulated = ATA_SHT_EMULATED, | 334 | .emulated = ATA_SHT_EMULATED, |
328 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 335 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
@@ -331,6 +338,8 @@ static struct scsi_host_template hpt36x_sht = { | |||
331 | .slave_configure = ata_scsi_slave_config, | 338 | .slave_configure = ata_scsi_slave_config, |
332 | .slave_destroy = ata_scsi_slave_destroy, | 339 | .slave_destroy = ata_scsi_slave_destroy, |
333 | .bios_param = ata_std_bios_param, | 340 | .bios_param = ata_std_bios_param, |
341 | .resume = ata_scsi_device_resume, | ||
342 | .suspend = ata_scsi_device_suspend, | ||
334 | }; | 343 | }; |
335 | 344 | ||
336 | /* | 345 | /* |
@@ -373,6 +382,27 @@ static struct ata_port_operations hpt366_port_ops = { | |||
373 | }; | 382 | }; |
374 | 383 | ||
375 | /** | 384 | /** |
385 | * hpt36x_init_chipset - common chip setup | ||
386 | * @dev: PCI device | ||
387 | * | ||
388 | * Perform the chip setup work that must be done at both init and | ||
389 | * resume time | ||
390 | */ | ||
391 | |||
392 | static void hpt36x_init_chipset(struct pci_dev *dev) | ||
393 | { | ||
394 | u8 drive_fast; | ||
395 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); | ||
396 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); | ||
397 | pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); | ||
398 | pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); | ||
399 | |||
400 | pci_read_config_byte(dev, 0x51, &drive_fast); | ||
401 | if (drive_fast & 0x80) | ||
402 | pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); | ||
403 | } | ||
404 | |||
405 | /** | ||
376 | * hpt36x_init_one - Initialise an HPT366/368 | 406 | * hpt36x_init_one - Initialise an HPT366/368 |
377 | * @dev: PCI device | 407 | * @dev: PCI device |
378 | * @id: Entry in match table | 408 | * @id: Entry in match table |
@@ -407,7 +437,6 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
407 | 437 | ||
408 | u32 class_rev; | 438 | u32 class_rev; |
409 | u32 reg1; | 439 | u32 reg1; |
410 | u8 drive_fast; | ||
411 | 440 | ||
412 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | 441 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); |
413 | class_rev &= 0xFF; | 442 | class_rev &= 0xFF; |
@@ -417,14 +446,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
417 | if (class_rev > 2) | 446 | if (class_rev > 2) |
418 | return -ENODEV; | 447 | return -ENODEV; |
419 | 448 | ||
420 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); | 449 | hpt36x_init_chipset(dev); |
421 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); | ||
422 | pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); | ||
423 | pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); | ||
424 | |||
425 | pci_read_config_byte(dev, 0x51, &drive_fast); | ||
426 | if (drive_fast & 0x80) | ||
427 | pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); | ||
428 | 450 | ||
429 | pci_read_config_dword(dev, 0x40, ®1); | 451 | pci_read_config_dword(dev, 0x40, ®1); |
430 | 452 | ||
@@ -445,9 +467,15 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
445 | return ata_pci_init_one(dev, port_info, 2); | 467 | return ata_pci_init_one(dev, port_info, 2); |
446 | } | 468 | } |
447 | 469 | ||
470 | static int hpt36x_reinit_one(struct pci_dev *dev) | ||
471 | { | ||
472 | hpt36x_init_chipset(dev); | ||
473 | return ata_pci_device_resume(dev); | ||
474 | } | ||
475 | |||
476 | |||
448 | static const struct pci_device_id hpt36x[] = { | 477 | static const struct pci_device_id hpt36x[] = { |
449 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, | 478 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, |
450 | |||
451 | { }, | 479 | { }, |
452 | }; | 480 | }; |
453 | 481 | ||
@@ -455,7 +483,9 @@ static struct pci_driver hpt36x_pci_driver = { | |||
455 | .name = DRV_NAME, | 483 | .name = DRV_NAME, |
456 | .id_table = hpt36x, | 484 | .id_table = hpt36x, |
457 | .probe = hpt36x_init_one, | 485 | .probe = hpt36x_init_one, |
458 | .remove = ata_pci_remove_one | 486 | .remove = ata_pci_remove_one, |
487 | .suspend = ata_pci_device_suspend, | ||
488 | .resume = hpt36x_reinit_one, | ||
459 | }; | 489 | }; |
460 | 490 | ||
461 | static int __init hpt36x_init(void) | 491 | static int __init hpt36x_init(void) |
@@ -463,13 +493,11 @@ static int __init hpt36x_init(void) | |||
463 | return pci_register_driver(&hpt36x_pci_driver); | 493 | return pci_register_driver(&hpt36x_pci_driver); |
464 | } | 494 | } |
465 | 495 | ||
466 | |||
467 | static void __exit hpt36x_exit(void) | 496 | static void __exit hpt36x_exit(void) |
468 | { | 497 | { |
469 | pci_unregister_driver(&hpt36x_pci_driver); | 498 | pci_unregister_driver(&hpt36x_pci_driver); |
470 | } | 499 | } |
471 | 500 | ||
472 | |||
473 | MODULE_AUTHOR("Alan Cox"); | 501 | MODULE_AUTHOR("Alan Cox"); |
474 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); | 502 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); |
475 | MODULE_LICENSE("GPL"); | 503 | MODULE_LICENSE("GPL"); |