18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> 38c2ecf20Sopenharmony_ci * Copyright (C) 2007 Bartlomiej Zolnierkiewicz 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * May be copied or modified under the terms of the GNU General Public License 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Development of this chipset driver was funded 88c2ecf20Sopenharmony_ci * by the nice folks at National Semiconductor. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Documentation: 118c2ecf20Sopenharmony_ci * Available from National Semiconductor 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/types.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <linux/pci.h> 198c2ecf20Sopenharmony_ci#include <linux/init.h> 208c2ecf20Sopenharmony_ci#include <linux/ide.h> 218c2ecf20Sopenharmony_ci#include <linux/pm.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <asm/io.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define DRV_NAME "sc1200" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define SC1200_REV_A 0x00 288c2ecf20Sopenharmony_ci#define SC1200_REV_B1 0x01 298c2ecf20Sopenharmony_ci#define SC1200_REV_B3 0x02 308c2ecf20Sopenharmony_ci#define SC1200_REV_C1 0x03 318c2ecf20Sopenharmony_ci#define SC1200_REV_D1 0x04 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define PCI_CLK_33 0x00 348c2ecf20Sopenharmony_ci#define PCI_CLK_48 0x01 358c2ecf20Sopenharmony_ci#define PCI_CLK_66 0x02 368c2ecf20Sopenharmony_ci#define PCI_CLK_33A 0x03 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic unsigned short sc1200_get_pci_clock (void) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci unsigned char chip_id, silicon_revision; 418c2ecf20Sopenharmony_ci unsigned int pci_clock; 428c2ecf20Sopenharmony_ci /* 438c2ecf20Sopenharmony_ci * Check the silicon revision, as not all versions of the chip 448c2ecf20Sopenharmony_ci * have the register with the fast PCI bus timings. 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_ci chip_id = inb (0x903c); 478c2ecf20Sopenharmony_ci silicon_revision = inb (0x903d); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci // Read the fast pci clock frequency 508c2ecf20Sopenharmony_ci if (chip_id == 0x04 && silicon_revision < SC1200_REV_B1) { 518c2ecf20Sopenharmony_ci pci_clock = PCI_CLK_33; 528c2ecf20Sopenharmony_ci } else { 538c2ecf20Sopenharmony_ci // check clock generator configuration (cfcc) 548c2ecf20Sopenharmony_ci // the clock is in bits 8 and 9 of this word 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci pci_clock = inw (0x901e); 578c2ecf20Sopenharmony_ci pci_clock >>= 8; 588c2ecf20Sopenharmony_ci pci_clock &= 0x03; 598c2ecf20Sopenharmony_ci if (pci_clock == PCI_CLK_33A) 608c2ecf20Sopenharmony_ci pci_clock = PCI_CLK_33; 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci return pci_clock; 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/* 668c2ecf20Sopenharmony_ci * Here are the standard PIO mode 0-4 timings for each "format". 678c2ecf20Sopenharmony_ci * Format-0 uses fast data reg timings, with slower command reg timings. 688c2ecf20Sopenharmony_ci * Format-1 uses fast timings for all registers, but won't work with all drives. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistatic const unsigned int sc1200_pio_timings[4][5] = 718c2ecf20Sopenharmony_ci {{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz 728c2ecf20Sopenharmony_ci {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz 738c2ecf20Sopenharmony_ci {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz 748c2ecf20Sopenharmony_ci {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131}}; // format1, 66Mhz 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* 778c2ecf20Sopenharmony_ci * After chip reset, the PIO timings are set to 0x00009172, which is not valid. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_ci//#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172) 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic void sc1200_tunepio(ide_drive_t *drive, u8 pio) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci ide_hwif_t *hwif = drive->hwif; 848c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(hwif->dev); 858c2ecf20Sopenharmony_ci unsigned int basereg = hwif->channel ? 0x50 : 0x40, format = 0; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci pci_read_config_dword(pdev, basereg + 4, &format); 888c2ecf20Sopenharmony_ci format = (format >> 31) & 1; 898c2ecf20Sopenharmony_ci if (format) 908c2ecf20Sopenharmony_ci format += sc1200_get_pci_clock(); 918c2ecf20Sopenharmony_ci pci_write_config_dword(pdev, basereg + ((drive->dn & 1) << 3), 928c2ecf20Sopenharmony_ci sc1200_pio_timings[format][pio]); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* 968c2ecf20Sopenharmony_ci * The SC1200 specifies that two drives sharing a cable cannot mix 978c2ecf20Sopenharmony_ci * UDMA/MDMA. It has to be one or the other, for the pair, though 988c2ecf20Sopenharmony_ci * different timings can still be chosen for each drive. We could 998c2ecf20Sopenharmony_ci * set the appropriate timing bits on the fly, but that might be 1008c2ecf20Sopenharmony_ci * a bit confusing. So, for now we statically handle this requirement 1018c2ecf20Sopenharmony_ci * by looking at our mate drive to see what it is capable of, before 1028c2ecf20Sopenharmony_ci * choosing a mode for our own drive. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_cistatic u8 sc1200_udma_filter(ide_drive_t *drive) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci ide_hwif_t *hwif = drive->hwif; 1078c2ecf20Sopenharmony_ci ide_drive_t *mate = ide_get_pair_dev(drive); 1088c2ecf20Sopenharmony_ci u16 *mateid; 1098c2ecf20Sopenharmony_ci u8 mask = hwif->ultra_mask; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci if (mate == NULL) 1128c2ecf20Sopenharmony_ci goto out; 1138c2ecf20Sopenharmony_ci mateid = mate->id; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci if (ata_id_has_dma(mateid) && __ide_dma_bad_drive(mate) == 0) { 1168c2ecf20Sopenharmony_ci if ((mateid[ATA_ID_FIELD_VALID] & 4) && 1178c2ecf20Sopenharmony_ci (mateid[ATA_ID_UDMA_MODES] & 7)) 1188c2ecf20Sopenharmony_ci goto out; 1198c2ecf20Sopenharmony_ci if (mateid[ATA_ID_MWDMA_MODES] & 7) 1208c2ecf20Sopenharmony_ci mask = 0; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ciout: 1238c2ecf20Sopenharmony_ci return mask; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic void sc1200_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct pci_dev *dev = to_pci_dev(hwif->dev); 1298c2ecf20Sopenharmony_ci unsigned int reg, timings; 1308c2ecf20Sopenharmony_ci unsigned short pci_clock; 1318c2ecf20Sopenharmony_ci unsigned int basereg = hwif->channel ? 0x50 : 0x40; 1328c2ecf20Sopenharmony_ci const u8 mode = drive->dma_mode; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci static const u32 udma_timing[3][3] = { 1358c2ecf20Sopenharmony_ci { 0x00921250, 0x00911140, 0x00911030 }, 1368c2ecf20Sopenharmony_ci { 0x00932470, 0x00922260, 0x00922140 }, 1378c2ecf20Sopenharmony_ci { 0x009436a1, 0x00933481, 0x00923261 }, 1388c2ecf20Sopenharmony_ci }; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci static const u32 mwdma_timing[3][3] = { 1418c2ecf20Sopenharmony_ci { 0x00077771, 0x00012121, 0x00002020 }, 1428c2ecf20Sopenharmony_ci { 0x000bbbb2, 0x00024241, 0x00013131 }, 1438c2ecf20Sopenharmony_ci { 0x000ffff3, 0x00035352, 0x00015151 }, 1448c2ecf20Sopenharmony_ci }; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci pci_clock = sc1200_get_pci_clock(); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci /* 1498c2ecf20Sopenharmony_ci * Note that each DMA mode has several timings associated with it. 1508c2ecf20Sopenharmony_ci * The correct timing depends on the fast PCI clock freq. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci if (mode >= XFER_UDMA_0) 1548c2ecf20Sopenharmony_ci timings = udma_timing[pci_clock][mode - XFER_UDMA_0]; 1558c2ecf20Sopenharmony_ci else 1568c2ecf20Sopenharmony_ci timings = mwdma_timing[pci_clock][mode - XFER_MW_DMA_0]; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci if ((drive->dn & 1) == 0) { 1598c2ecf20Sopenharmony_ci pci_read_config_dword(dev, basereg + 4, ®); 1608c2ecf20Sopenharmony_ci timings |= reg & 0x80000000; /* preserve PIO format bit */ 1618c2ecf20Sopenharmony_ci pci_write_config_dword(dev, basereg + 4, timings); 1628c2ecf20Sopenharmony_ci } else 1638c2ecf20Sopenharmony_ci pci_write_config_dword(dev, basereg + 12, timings); 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci/* Replacement for the standard ide_dma_end action in 1678c2ecf20Sopenharmony_ci * dma_proc. 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * returns 1 on error, 0 otherwise 1708c2ecf20Sopenharmony_ci */ 1718c2ecf20Sopenharmony_cistatic int sc1200_dma_end(ide_drive_t *drive) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci ide_hwif_t *hwif = drive->hwif; 1748c2ecf20Sopenharmony_ci unsigned long dma_base = hwif->dma_base; 1758c2ecf20Sopenharmony_ci u8 dma_stat; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci dma_stat = inb(dma_base+2); /* get DMA status */ 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci if (!(dma_stat & 4)) 1808c2ecf20Sopenharmony_ci printk(" ide_dma_end dma_stat=%0x err=%x newerr=%x\n", 1818c2ecf20Sopenharmony_ci dma_stat, ((dma_stat&7)!=4), ((dma_stat&2)==2)); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */ 1848c2ecf20Sopenharmony_ci outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */ 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci return (dma_stat & 7) != 4; /* verify good DMA status */ 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/* 1908c2ecf20Sopenharmony_ci * sc1200_set_pio_mode() handles setting of PIO modes 1918c2ecf20Sopenharmony_ci * for both the chipset and drive. 1928c2ecf20Sopenharmony_ci * 1938c2ecf20Sopenharmony_ci * All existing BIOSs for this chipset guarantee that all drives 1948c2ecf20Sopenharmony_ci * will have valid default PIO timings set up before we get here. 1958c2ecf20Sopenharmony_ci */ 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic void sc1200_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci int mode = -1; 2008c2ecf20Sopenharmony_ci const u8 pio = drive->pio_mode - XFER_PIO_0; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* 2038c2ecf20Sopenharmony_ci * bad abuse of ->set_pio_mode interface 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_ci switch (pio) { 2068c2ecf20Sopenharmony_ci case 200: mode = XFER_UDMA_0; break; 2078c2ecf20Sopenharmony_ci case 201: mode = XFER_UDMA_1; break; 2088c2ecf20Sopenharmony_ci case 202: mode = XFER_UDMA_2; break; 2098c2ecf20Sopenharmony_ci case 100: mode = XFER_MW_DMA_0; break; 2108c2ecf20Sopenharmony_ci case 101: mode = XFER_MW_DMA_1; break; 2118c2ecf20Sopenharmony_ci case 102: mode = XFER_MW_DMA_2; break; 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci if (mode != -1) { 2148c2ecf20Sopenharmony_ci printk("SC1200: %s: changing (U)DMA mode\n", drive->name); 2158c2ecf20Sopenharmony_ci ide_dma_off_quietly(drive); 2168c2ecf20Sopenharmony_ci if (ide_set_dma_mode(drive, mode) == 0 && 2178c2ecf20Sopenharmony_ci (drive->dev_flags & IDE_DFLAG_USING_DMA)) 2188c2ecf20Sopenharmony_ci hwif->dma_ops->dma_host_set(drive, 1); 2198c2ecf20Sopenharmony_ci return; 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci sc1200_tunepio(drive, pio); 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 2268c2ecf20Sopenharmony_cistruct sc1200_saved_state { 2278c2ecf20Sopenharmony_ci u32 regs[8]; 2288c2ecf20Sopenharmony_ci}; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic int sc1200_suspend (struct pci_dev *dev, pm_message_t state) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci printk("SC1200: suspend(%u)\n", state.event); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci /* 2358c2ecf20Sopenharmony_ci * we only save state when going from full power to less 2368c2ecf20Sopenharmony_ci */ 2378c2ecf20Sopenharmony_ci if (state.event == PM_EVENT_ON) { 2388c2ecf20Sopenharmony_ci struct ide_host *host = pci_get_drvdata(dev); 2398c2ecf20Sopenharmony_ci struct sc1200_saved_state *ss = host->host_priv; 2408c2ecf20Sopenharmony_ci unsigned int r; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci /* 2438c2ecf20Sopenharmony_ci * save timing registers 2448c2ecf20Sopenharmony_ci * (this may be unnecessary if BIOS also does it) 2458c2ecf20Sopenharmony_ci */ 2468c2ecf20Sopenharmony_ci for (r = 0; r < 8; r++) 2478c2ecf20Sopenharmony_ci pci_read_config_dword(dev, 0x40 + r * 4, &ss->regs[r]); 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci pci_disable_device(dev); 2518c2ecf20Sopenharmony_ci pci_set_power_state(dev, pci_choose_state(dev, state)); 2528c2ecf20Sopenharmony_ci return 0; 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic int sc1200_resume (struct pci_dev *dev) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci struct ide_host *host = pci_get_drvdata(dev); 2588c2ecf20Sopenharmony_ci struct sc1200_saved_state *ss = host->host_priv; 2598c2ecf20Sopenharmony_ci unsigned int r; 2608c2ecf20Sopenharmony_ci int i; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci i = pci_enable_device(dev); 2638c2ecf20Sopenharmony_ci if (i) 2648c2ecf20Sopenharmony_ci return i; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci /* 2678c2ecf20Sopenharmony_ci * restore timing registers 2688c2ecf20Sopenharmony_ci * (this may be unnecessary if BIOS also does it) 2698c2ecf20Sopenharmony_ci */ 2708c2ecf20Sopenharmony_ci for (r = 0; r < 8; r++) 2718c2ecf20Sopenharmony_ci pci_write_config_dword(dev, 0x40 + r * 4, ss->regs[r]); 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci return 0; 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci#endif 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic const struct ide_port_ops sc1200_port_ops = { 2788c2ecf20Sopenharmony_ci .set_pio_mode = sc1200_set_pio_mode, 2798c2ecf20Sopenharmony_ci .set_dma_mode = sc1200_set_dma_mode, 2808c2ecf20Sopenharmony_ci .udma_filter = sc1200_udma_filter, 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic const struct ide_dma_ops sc1200_dma_ops = { 2848c2ecf20Sopenharmony_ci .dma_host_set = ide_dma_host_set, 2858c2ecf20Sopenharmony_ci .dma_setup = ide_dma_setup, 2868c2ecf20Sopenharmony_ci .dma_start = ide_dma_start, 2878c2ecf20Sopenharmony_ci .dma_end = sc1200_dma_end, 2888c2ecf20Sopenharmony_ci .dma_test_irq = ide_dma_test_irq, 2898c2ecf20Sopenharmony_ci .dma_lost_irq = ide_dma_lost_irq, 2908c2ecf20Sopenharmony_ci .dma_timer_expiry = ide_dma_sff_timer_expiry, 2918c2ecf20Sopenharmony_ci .dma_sff_read_status = ide_dma_sff_read_status, 2928c2ecf20Sopenharmony_ci}; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic const struct ide_port_info sc1200_chipset = { 2958c2ecf20Sopenharmony_ci .name = DRV_NAME, 2968c2ecf20Sopenharmony_ci .port_ops = &sc1200_port_ops, 2978c2ecf20Sopenharmony_ci .dma_ops = &sc1200_dma_ops, 2988c2ecf20Sopenharmony_ci .host_flags = IDE_HFLAG_SERIALIZE | 2998c2ecf20Sopenharmony_ci IDE_HFLAG_POST_SET_MODE | 3008c2ecf20Sopenharmony_ci IDE_HFLAG_ABUSE_DMA_MODES, 3018c2ecf20Sopenharmony_ci .pio_mask = ATA_PIO4, 3028c2ecf20Sopenharmony_ci .mwdma_mask = ATA_MWDMA2, 3038c2ecf20Sopenharmony_ci .udma_mask = ATA_UDMA2, 3048c2ecf20Sopenharmony_ci}; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistatic int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci struct sc1200_saved_state *ss = NULL; 3098c2ecf20Sopenharmony_ci int rc; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 3128c2ecf20Sopenharmony_ci ss = kmalloc(sizeof(*ss), GFP_KERNEL); 3138c2ecf20Sopenharmony_ci if (ss == NULL) 3148c2ecf20Sopenharmony_ci return -ENOMEM; 3158c2ecf20Sopenharmony_ci#endif 3168c2ecf20Sopenharmony_ci rc = ide_pci_init_one(dev, &sc1200_chipset, ss); 3178c2ecf20Sopenharmony_ci if (rc) 3188c2ecf20Sopenharmony_ci kfree(ss); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci return rc; 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic const struct pci_device_id sc1200_pci_tbl[] = { 3248c2ecf20Sopenharmony_ci { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0}, 3258c2ecf20Sopenharmony_ci { 0, }, 3268c2ecf20Sopenharmony_ci}; 3278c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic struct pci_driver sc1200_pci_driver = { 3308c2ecf20Sopenharmony_ci .name = "SC1200_IDE", 3318c2ecf20Sopenharmony_ci .id_table = sc1200_pci_tbl, 3328c2ecf20Sopenharmony_ci .probe = sc1200_init_one, 3338c2ecf20Sopenharmony_ci .remove = ide_pci_remove, 3348c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 3358c2ecf20Sopenharmony_ci .suspend = sc1200_suspend, 3368c2ecf20Sopenharmony_ci .resume = sc1200_resume, 3378c2ecf20Sopenharmony_ci#endif 3388c2ecf20Sopenharmony_ci}; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic int __init sc1200_ide_init(void) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci return ide_pci_register_driver(&sc1200_pci_driver); 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cistatic void __exit sc1200_ide_exit(void) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci pci_unregister_driver(&sc1200_pci_driver); 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cimodule_init(sc1200_ide_init); 3518c2ecf20Sopenharmony_cimodule_exit(sc1200_ide_exit); 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ciMODULE_AUTHOR("Mark Lord"); 3548c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE"); 3558c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 356