pata_hpt366.c revision 82beb5d89456a4c8329676985004b93a7ded5b5a
1669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/* 2669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Libata driver for the highpoint 366 and 368 UDMA66 ATA controllers. 3669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 4669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * This driver is heavily based upon: 5669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 6669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 7669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 8669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> 9669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Portions Copyright (C) 2001 Sun Microsystems, Inc. 10669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Portions Copyright (C) 2003 Red Hat Inc 11669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 12669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 13669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * TODO 14669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Maybe PLL mode 15669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Look into engine reset on timeout errors. Should not be 16669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * required. 17669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 18669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 19669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 20669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/kernel.h> 21669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/module.h> 22669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/pci.h> 23669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/init.h> 24669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/blkdev.h> 25669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/delay.h> 26669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <scsi/scsi_host.h> 27669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/libata.h> 28669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 29669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#define DRV_NAME "pata_hpt366" 3082beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov#define DRV_VERSION "0.6.7" 31669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 32669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstruct hpt_clock { 336ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo u8 xfer_mode; 34669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u32 timing; 35669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 36669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 37669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/* key for bus clock timings 38669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * bit 3982beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. 4082beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * cycles = value + 1 4182beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 4:7 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. 4282beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * cycles = value + 1 4382beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 8:11 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file 44669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * register access. 4582beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 12:15 cmd_low_time. Active time of DIOW_/DIOR_ during task file 46669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * register access. 4782beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 16:18 udma_cycle_time. Clock cycles for UDMA xfer? 4882beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 19:21 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. 4982beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 22:24 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file 50669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * register access. 5182beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 28 UDMA enable. 5282beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 29 DMA enable. 5382beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * 30 PIO_MST enable. If set, the chip is in bus master mode during 5482beb5d89456a4c8329676985004b93a7ded5b5aSergei Shtylyov * PIO xfer. 55669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 31 FIFO enable. 56669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 57669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 58669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const struct hpt_clock hpt366_40[] = { 59669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_4, 0x900fd943 }, 60669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_3, 0x900ad943 }, 61669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_2, 0x900bd943 }, 62669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_1, 0x9008d943 }, 63669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_0, 0x9008d943 }, 64669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 65669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_2, 0xa008d943 }, 66669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_1, 0xa010d955 }, 67669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_0, 0xa010d9fc }, 68669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 69669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_4, 0xc008d963 }, 70669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_3, 0xc010d974 }, 71669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_2, 0xc010d997 }, 72669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_1, 0xc010d9c7 }, 73669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_0, 0xc018d9d9 }, 74669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0, 0x0120d9d9 } 75669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 76669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 77669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const struct hpt_clock hpt366_33[] = { 78669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_4, 0x90c9a731 }, 79669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_3, 0x90cfa731 }, 80669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_2, 0x90caa731 }, 81669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_1, 0x90cba731 }, 82669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_0, 0x90c8a731 }, 83669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 84669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_2, 0xa0c8a731 }, 85669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */ 86669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_0, 0xa0c8a797 }, 87669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 88669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_4, 0xc0c8a731 }, 89669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_3, 0xc0c8a742 }, 90669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_2, 0xc0d0a753 }, 91669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */ 92669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ 93669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0, 0x0120a7a7 } 94669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 95669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 96669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const struct hpt_clock hpt366_25[] = { 97669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_4, 0x90c98521 }, 98669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_3, 0x90cf8521 }, 99669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_2, 0x90cf8521 }, 100669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_1, 0x90cb8521 }, 101669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_UDMA_0, 0x90cb8521 }, 102669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 103669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_2, 0xa0ca8521 }, 104669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_1, 0xa0ca8532 }, 105669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_MW_DMA_0, 0xa0ca8575 }, 106669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 107669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_4, 0xc0ca8521 }, 108669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_3, 0xc0ca8532 }, 109669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_2, 0xc0ca8542 }, 110669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_1, 0xc0d08572 }, 111669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { XFER_PIO_0, 0xc0d08585 }, 112669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0, 0x01208585 } 113669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 114669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 115669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const char *bad_ata33[] = { 116669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", 117669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", 118669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", 119669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 90510D4", 120669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", 121669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", 122669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", 123669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik NULL 124669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 125669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 126669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const char *bad_ata66_4[] = { 127669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307075", 128669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307060", 129669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307045", 130669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307030", 131669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307020", 132669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-307015", 133669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-305040", 134669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-305030", 135669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IBM-DTLA-305020", 136669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IC35L010AVER07-0", 137669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IC35L020AVER07-0", 138669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IC35L030AVER07-0", 139669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IC35L040AVER07-0", 140669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "IC35L060AVER07-0", 141669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "WDC AC310200R", 142669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik NULL 143669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 144669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 145669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic const char *bad_ata66_3[] = { 146669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik "WDC AC310200R", 147669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik NULL 148669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 149669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 150669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) 151669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 1528bfa79fcb81d2bdb043f60ab4171704467808b55Tejun Heo unsigned char model_num[ATA_ID_PROD_LEN + 1]; 153669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik int i = 0; 154669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 1558bfa79fcb81d2bdb043f60ab4171704467808b55Tejun Heo ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); 156669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 1578bfa79fcb81d2bdb043f60ab4171704467808b55Tejun Heo while (list[i] != NULL) { 1588bfa79fcb81d2bdb043f60ab4171704467808b55Tejun Heo if (!strcmp(list[i], model_num)) { 15985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", 160669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik modestr, list[i]); 161669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return 1; 162669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 163669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik i++; 164669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 165669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return 0; 166669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 167669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 168669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 169669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * hpt366_filter - mode selection filter 170669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: ATA device 171669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 172669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Block UDMA on devices that cause trouble with this controller. 173669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 17485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 175a76b62ca70662cd0ca98edf366c6637009a95f7dAlan Coxstatic unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask) 176669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 177669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (adev->class == ATA_DEV_ATA) { 178669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) 179669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik mask &= ~ATA_MASK_UDMA; 180669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) 1816ddd68615ae9b21096545d7d6ab0f04113ae8b42Alan Cox mask &= ~(0xF8 << ATA_SHIFT_UDMA); 182669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) 1836ddd68615ae9b21096545d7d6ab0f04113ae8b42Alan Cox mask &= ~(0xF0 << ATA_SHIFT_UDMA); 1843ee89f177e3cef0b5b024bcb6df683a3fa7d795fTejun Heo } else if (adev->class == ATA_DEV_ATAPI) 1853ee89f177e3cef0b5b024bcb6df683a3fa7d795fTejun Heo mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); 1863ee89f177e3cef0b5b024bcb6df683a3fa7d795fTejun Heo 1879363c3825ea9ad76561eb48a395349dd29211ed6Tejun Heo return ata_bmdma_mode_filter(adev, mask); 188669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 189669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 190fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Coxstatic int hpt36x_cable_detect(struct ata_port *ap) 191fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox{ 192fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox struct pci_dev *pdev = to_pci_dev(ap->host->dev); 193bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo u8 ata66; 194fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox 195bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo /* 196bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo * Each channel of pata_hpt366 occupies separate PCI function 197bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo * as the primary channel and bit1 indicates the cable type. 198bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo */ 199fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox pci_read_config_byte(pdev, 0x5A, &ata66); 200bab5b32a537edc83ff86bff91e46f328339f49f8Tejun Heo if (ata66 & 2) 201fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox return ATA_CBL_PATA40; 202fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox return ATA_CBL_PATA80; 203fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox} 204fecfda5d88dcc3775f72d6f3a55d11b77c67f878Alan Cox 2056ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heostatic void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, 2066ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo u8 mode) 207669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 2086ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo struct hpt_clock *clocks = ap->host->private_data; 209669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 2106ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo u32 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 2116ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo u32 addr2 = 0x51 + 4 * ap->port_no; 2126ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo u32 mask, reg; 213669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u8 fast; 214669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 215669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Fast interrupt prediction disable, hold off interrupt disable */ 216669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_byte(pdev, addr2, &fast); 217669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (fast & 0x80) { 218669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik fast &= ~0x80; 219669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_write_config_byte(pdev, addr2, fast); 220669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 22185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 2226ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo /* determine timing mask and find matching clock entry */ 2236ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo if (mode < XFER_MW_DMA_0) 2246ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo mask = 0xc1f8ffff; 2256ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo else if (mode < XFER_UDMA_0) 2266ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo mask = 0x303800ff; 2276ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo else 2286ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo mask = 0x30070000; 2296ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo 2306ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo while (clocks->xfer_mode) { 2316ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo if (clocks->xfer_mode == mode) 2326ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo break; 2336ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo clocks++; 2346ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo } 2356ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo if (!clocks->xfer_mode) 2366ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo BUG(); 2376ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo 2386ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo /* 2396ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * Combine new mode bits with old config bits and disable 2406ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * on-chip PIO FIFO/buffer (and PIO MST mode as well) to avoid 2416ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * problems handling I/O errors later. 2426ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo */ 243669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_dword(pdev, addr1, ®); 2446ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000; 2456ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo pci_write_config_dword(pdev, addr1, reg); 2466ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo} 2476ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo 2486ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo/** 2496ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * hpt366_set_piomode - PIO setup 2506ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * @ap: ATA interface 2516ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * @adev: device on the interface 2526ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * 2536ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo * Perform PIO mode setup. 2546ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo */ 2556ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo 2566ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heostatic void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev) 2576ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo{ 2586ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo hpt366_set_mode(ap, adev, adev->pio_mode); 259669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 260669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 261669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 262669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * hpt366_set_dmamode - DMA timing setup 263669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @ap: ATA interface 264669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: Device being configured 265669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 266669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Set up the channel for MWDMA or UDMA modes. Much the same as with 267669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * PIO, load the mode number and then set MWDMA or UDMA flag. 268669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 26985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 270669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev) 271669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 2726ecb6f25d3a52c0d032aa73bde1ff9bc454aa66cTejun Heo hpt366_set_mode(ap, adev, adev->dma_mode); 273669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 274669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 275669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct scsi_host_template hpt36x_sht = { 27668d1d07b510bb57a504588adc2bd2758adea0965Tejun Heo ATA_BMDMA_SHT(DRV_NAME), 277669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 278669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 279669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/* 280669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Configuration for HPT366/68 281669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 28285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 283669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct ata_port_operations hpt366_port_ops = { 284029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .inherits = &ata_bmdma_port_ops, 285029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .cable_detect = hpt36x_cable_detect, 286029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .mode_filter = hpt366_filter, 287669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .set_piomode = hpt366_set_piomode, 288669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .set_dmamode = hpt366_set_dmamode, 28985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik}; 290669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 291669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 292aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox * hpt36x_init_chipset - common chip setup 293aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox * @dev: PCI device 294aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox * 295aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox * Perform the chip setup work that must be done at both init and 296aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox * resume time 297aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox */ 298aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox 299aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Coxstatic void hpt36x_init_chipset(struct pci_dev *dev) 300aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox{ 301aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox u8 drive_fast; 302aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); 303aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); 304aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); 305aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); 306aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox 307aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_read_config_byte(dev, 0x51, &drive_fast); 308aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox if (drive_fast & 0x80) 309aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); 310aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox} 311aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox 312aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox/** 313669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * hpt36x_init_one - Initialise an HPT366/368 314669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @dev: PCI device 315669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @id: Entry in match table 316669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 317669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Initialise an HPT36x device. There are some interesting complications 318669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * here. Firstly the chip may report 366 and be one of several variants. 319669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Secondly all the timings depend on the clock for the chip which we must 320669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * detect and look up 321669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 322669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * This is the known chip mappings. It may be missing a couple of later 323669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * releases. 324669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 325669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Chip version PCI Rev Notes 326669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * HPT366 4 (HPT366) 0 UDMA66 327669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * HPT366 4 (HPT366) 1 UDMA66 328669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * HPT368 4 (HPT366) 2 UDMA66 329669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * HPT37x/30x 4 (HPT366) 3+ Other driver 330669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 331669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 33285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 333669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) 334669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 3351626aeb881236c8cb022b5e4ca594146a951d669Tejun Heo static const struct ata_port_info info_hpt366 = { 3361d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik .flags = ATA_FLAG_SLAVE_POSS, 33714bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .pio_mask = ATA_PIO4, 33814bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .mwdma_mask = ATA_MWDMA2, 339bf6263a853c9c143bf03f0a6fdcc68ab714fb5f5Jeff Garzik .udma_mask = ATA_UDMA4, 340669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .port_ops = &hpt366_port_ops 341669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik }; 342887125e3740283be25564bfc6fb5d24974b651abTejun Heo const struct ata_port_info *ppi[] = { &info_hpt366, NULL }; 343669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 344887125e3740283be25564bfc6fb5d24974b651abTejun Heo void *hpriv = NULL; 345669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u32 class_rev; 346669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u32 reg1; 347f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo int rc; 348f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo 349f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo rc = pcim_enable_device(dev); 350f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo if (rc) 351f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo return rc; 352669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 353669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 354669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik class_rev &= 0xFF; 35585cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 356669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* May be a later chip in disguise. Check */ 357669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Newer chips are not in the HPT36x driver. Ignore them */ 358669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (class_rev > 2) 359669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return -ENODEV; 360669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 361aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox hpt36x_init_chipset(dev); 362669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 363669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_dword(dev, 0x40, ®1); 36485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 365669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* PCI clocking determines the ATA timing values to use */ 366669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* info_hpt366 is safe against re-entry so we can scribble on it */ 3672c136efcf6f58d07512c4df83eb494597fe0d229OGAWA Hirofumi switch((reg1 & 0x700) >> 8) { 3682456eb819be7aa2cac73359c2855dfa30e46d75aTejun Heo case 9: 369887125e3740283be25564bfc6fb5d24974b651abTejun Heo hpriv = &hpt366_40; 370669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik break; 3712456eb819be7aa2cac73359c2855dfa30e46d75aTejun Heo case 5: 372887125e3740283be25564bfc6fb5d24974b651abTejun Heo hpriv = &hpt366_25; 373669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik break; 374669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik default: 375887125e3740283be25564bfc6fb5d24974b651abTejun Heo hpriv = &hpt366_33; 376669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik break; 377669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 378669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Now kick off ATA set up */ 3799363c3825ea9ad76561eb48a395349dd29211ed6Tejun Heo return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv); 380669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 381669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 382438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#ifdef CONFIG_PM 383aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Coxstatic int hpt36x_reinit_one(struct pci_dev *dev) 384aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox{ 385f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo struct ata_host *host = dev_get_drvdata(&dev->dev); 386f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo int rc; 387f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo 388f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo rc = ata_pci_device_do_resume(dev); 389f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo if (rc) 390f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo return rc; 391aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox hpt36x_init_chipset(dev); 392f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo ata_host_resume(host); 393f08048e94564d009b19038cfbdd800aa83e79c7fTejun Heo return 0; 394aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox} 395438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#endif 396aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox 3972d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzikstatic const struct pci_device_id hpt36x[] = { 3982d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, 3992d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { }, 400669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 401669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 402669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct pci_driver hpt36x_pci_driver = { 4032d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik .name = DRV_NAME, 404669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .id_table = hpt36x, 405669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .probe = hpt36x_init_one, 406aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox .remove = ata_pci_remove_one, 407438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#ifdef CONFIG_PM 408aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox .suspend = ata_pci_device_suspend, 409aa54ab1eff30f1e5859acf4e15f0730288373ee5Alan Cox .resume = hpt36x_reinit_one, 410438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#endif 411669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 412669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 413669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic int __init hpt36x_init(void) 414669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 415669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return pci_register_driver(&hpt36x_pci_driver); 416669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 417669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 418669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void __exit hpt36x_exit(void) 419669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 420669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_unregister_driver(&hpt36x_pci_driver); 421669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 422669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 423669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_AUTHOR("Alan Cox"); 424669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); 425669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_LICENSE("GPL"); 426669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_DEVICE_TABLE(pci, hpt36x); 427669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_VERSION(DRV_VERSION); 428669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 429669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikmodule_init(hpt36x_init); 430669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikmodule_exit(hpt36x_exit); 431