aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_hpt366.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_hpt366.c')
-rw-r--r--drivers/ata/pata_hpt366.c58
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
32struct hpt_clock { 32struct 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
223static int hpt36x_pre_reset(struct ata_port *ap) 223static 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
392static 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, &reg1); 451 pci_read_config_dword(dev, 0x40, &reg1);
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
470static int hpt36x_reinit_one(struct pci_dev *dev)
471{
472 hpt36x_init_chipset(dev);
473 return ata_pci_device_resume(dev);
474}
475
476
448static const struct pci_device_id hpt36x[] = { 477static 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
461static int __init hpt36x_init(void) 491static 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
467static void __exit hpt36x_exit(void) 496static 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
473MODULE_AUTHOR("Alan Cox"); 501MODULE_AUTHOR("Alan Cox");
474MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); 502MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368");
475MODULE_LICENSE("GPL"); 503MODULE_LICENSE("GPL");