diff options
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/Makefile | 1 | ||||
-rw-r--r-- | drivers/ide/pci/cmd64x.c | 45 | ||||
-rw-r--r-- | drivers/ide/pci/delkin_cb.c | 1 | ||||
-rw-r--r-- | drivers/ide/pci/hpt366.c | 5 | ||||
-rw-r--r-- | drivers/ide/pci/jmicron.c | 29 | ||||
-rw-r--r-- | drivers/ide/pci/pdc202xx_new.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/scc_pata.c | 858 |
7 files changed, 909 insertions, 33 deletions
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 6591ff4753cb..95d1ea8f1f14 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -3,6 +3,7 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o | |||
3 | obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o | 3 | obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o |
4 | obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o | 4 | obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o |
5 | obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o | 5 | obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o |
6 | obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o | ||
6 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o | 7 | obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o |
7 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o | 8 | obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o |
8 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o | 9 | obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o |
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index b0d4825c56a9..561197f7b5bb 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 | 1 | /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 |
2 | * | 2 | * |
3 | * linux/drivers/ide/pci/cmd64x.c Version 1.41 Feb 3, 2007 | 3 | * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007 |
4 | * | 4 | * |
5 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. | 5 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. |
6 | * Note, this driver is not used at all on other systems because | 6 | * Note, this driver is not used at all on other systems because |
@@ -189,6 +189,11 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |||
189 | 189 | ||
190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ | 190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ |
191 | 191 | ||
192 | static u8 quantize_timing(int timing, int quant) | ||
193 | { | ||
194 | return (timing + quant - 1) / quant; | ||
195 | } | ||
196 | |||
192 | /* | 197 | /* |
193 | * This routine writes the prepared setup/active/recovery counts | 198 | * This routine writes the prepared setup/active/recovery counts |
194 | * for a drive into the cmd646 chipset registers to active them. | 199 | * for a drive into the cmd646 chipset registers to active them. |
@@ -268,47 +273,37 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ | |||
268 | */ | 273 | */ |
269 | static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) | 274 | static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) |
270 | { | 275 | { |
271 | int setup_time, active_time, recovery_time; | 276 | int setup_time, active_time, cycle_time; |
272 | int clock_time, pio_mode, cycle_time; | 277 | u8 cycle_count, setup_count, active_count, recovery_count; |
273 | u8 recovery_count2, cycle_count; | 278 | u8 pio_mode; |
274 | int setup_count, active_count, recovery_count; | 279 | int clock_time = 1000 / system_bus_clock(); |
275 | int bus_speed = system_bus_clock(); | 280 | ide_pio_data_t pio; |
276 | ide_pio_data_t d; | ||
277 | 281 | ||
278 | pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d); | 282 | pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); |
279 | cycle_time = d.cycle_time; | 283 | cycle_time = pio.cycle_time; |
280 | 284 | ||
281 | /* | ||
282 | * I copied all this complicated stuff from cmd640.c and made a few | ||
283 | * minor changes. For now I am just going to pray that it is correct. | ||
284 | */ | ||
285 | setup_time = ide_pio_timings[pio_mode].setup_time; | 285 | setup_time = ide_pio_timings[pio_mode].setup_time; |
286 | active_time = ide_pio_timings[pio_mode].active_time; | 286 | active_time = ide_pio_timings[pio_mode].active_time; |
287 | recovery_time = cycle_time - (setup_time + active_time); | ||
288 | clock_time = 1000 / bus_speed; | ||
289 | cycle_count = (cycle_time + clock_time - 1) / clock_time; | ||
290 | |||
291 | setup_count = (setup_time + clock_time - 1) / clock_time; | ||
292 | 287 | ||
293 | active_count = (active_time + clock_time - 1) / clock_time; | 288 | setup_count = quantize_timing( setup_time, clock_time); |
289 | cycle_count = quantize_timing( cycle_time, clock_time); | ||
290 | active_count = quantize_timing(active_time, clock_time); | ||
294 | 291 | ||
295 | recovery_count = (recovery_time + clock_time - 1) / clock_time; | 292 | recovery_count = cycle_count - active_count; |
296 | recovery_count2 = cycle_count - (setup_count + active_count); | 293 | /* program_drive_counts() takes care of zero recovery cycles */ |
297 | if (recovery_count2 > recovery_count) | ||
298 | recovery_count = recovery_count2; | ||
299 | if (recovery_count > 16) { | 294 | if (recovery_count > 16) { |
300 | active_count += recovery_count - 16; | 295 | active_count += recovery_count - 16; |
301 | recovery_count = 16; | 296 | recovery_count = 16; |
302 | } | 297 | } |
303 | if (active_count > 16) | 298 | if (active_count > 16) |
304 | active_count = 16; /* maximum allowed by cmd646 */ | 299 | active_count = 16; /* maximum allowed by cmd64x */ |
305 | 300 | ||
306 | program_drive_counts (drive, setup_count, active_count, recovery_count); | 301 | program_drive_counts (drive, setup_count, active_count, recovery_count); |
307 | 302 | ||
308 | cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " | 303 | cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " |
309 | "clocks=%d/%d/%d\n", | 304 | "clocks=%d/%d/%d\n", |
310 | drive->name, mode_wanted, pio_mode, cycle_time, | 305 | drive->name, mode_wanted, pio_mode, cycle_time, |
311 | d.overridden ? " (overriding vendor mode)" : "", | 306 | pio.overridden ? " (overriding vendor mode)" : "", |
312 | setup_count, active_count, recovery_count); | 307 | setup_count, active_count, recovery_count); |
313 | 308 | ||
314 | return pio_mode; | 309 | return pio_mode; |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index d4b753e70119..dd7ec37fdeab 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -108,6 +108,7 @@ delkin_cb_remove (struct pci_dev *dev) | |||
108 | 108 | ||
109 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { | 109 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { |
110 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 110 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
111 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
111 | { 0, }, | 112 | { 0, }, |
112 | }; | 113 | }; |
113 | MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl); | 114 | MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl); |
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 60ecdc258c7c..ab6fa271aeb3 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/hpt366.c Version 1.01 Dec 23, 2006 | 2 | * linux/drivers/ide/pci/hpt366.c Version 1.02 Apr 18, 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
6 | * Portions Copyright (C) 2003 Red Hat Inc | 6 | * Portions Copyright (C) 2003 Red Hat Inc |
7 | * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. | 7 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. |
8 | * | 8 | * |
9 | * Thanks to HighPoint Technologies for their assistance, and hardware. | 9 | * Thanks to HighPoint Technologies for their assistance, and hardware. |
10 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his | 10 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his |
@@ -494,6 +494,7 @@ static struct hpt_info hpt302n __devinitdata = { | |||
494 | .chip_type = HPT302N, | 494 | .chip_type = HPT302N, |
495 | .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, | 495 | .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, |
496 | .dpll_clk = 77, | 496 | .dpll_clk = 77, |
497 | .settings = hpt37x_settings | ||
497 | }; | 498 | }; |
498 | 499 | ||
499 | static struct hpt_info hpt371n __devinitdata = { | 500 | static struct hpt_info hpt371n __devinitdata = { |
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index 53f25500c22b..be4fc96c29e0 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c | |||
@@ -240,12 +240,31 @@ static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_devi | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | /* If libata is configured, jmicron PCI quirk will configure it such | ||
244 | * that the SATA ports are in AHCI function while the PATA ports are | ||
245 | * in a separate IDE function. In such cases, match device class and | ||
246 | * attach only to IDE. If libata isn't configured, keep the old | ||
247 | * behavior for backward compatibility. | ||
248 | */ | ||
249 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | ||
250 | #define JMB_CLASS PCI_CLASS_STORAGE_IDE << 8 | ||
251 | #define JMB_CLASS_MASK 0xffff00 | ||
252 | #else | ||
253 | #define JMB_CLASS 0 | ||
254 | #define JMB_CLASS_MASK 0 | ||
255 | #endif | ||
256 | |||
243 | static struct pci_device_id jmicron_pci_tbl[] = { | 257 | static struct pci_device_id jmicron_pci_tbl[] = { |
244 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 258 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, |
245 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 259 | PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0}, |
246 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 260 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, |
247 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, | 261 | PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1}, |
248 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, | 262 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, |
263 | PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2}, | ||
264 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, | ||
265 | PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3}, | ||
266 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, | ||
267 | PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4}, | ||
249 | { 0, }, | 268 | { 0, }, |
250 | }; | 269 | }; |
251 | 270 | ||
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 6ceb25bc5a7b..ace98929cc3d 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -255,7 +255,7 @@ static int config_chipset_for_dma(ide_drive_t *drive) | |||
255 | printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); | 255 | printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); |
256 | } | 256 | } |
257 | 257 | ||
258 | if (drive->media != ide_disk) | 258 | if (drive->media != ide_disk && drive->media != ide_cdrom) |
259 | return 0; | 259 | return 0; |
260 | 260 | ||
261 | if (id->capability & 4) { | 261 | if (id->capability & 4) { |
@@ -545,6 +545,7 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) | |||
545 | 545 | ||
546 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; | 546 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; |
547 | 547 | ||
548 | hwif->atapi_dma = 1; | ||
548 | hwif->ultra_mask = 0x7f; | 549 | hwif->ultra_mask = 0x7f; |
549 | hwif->mwdma_mask = 0x07; | 550 | hwif->mwdma_mask = 0x07; |
550 | 551 | ||
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c new file mode 100644 index 000000000000..f84bf791f72e --- /dev/null +++ b/drivers/ide/pci/scc_pata.c | |||
@@ -0,0 +1,858 @@ | |||
1 | /* | ||
2 | * Support for IDE interfaces on Celleb platform | ||
3 | * | ||
4 | * (C) Copyright 2006 TOSHIBA CORPORATION | ||
5 | * | ||
6 | * This code is based on drivers/ide/pci/siimage.c: | ||
7 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> | ||
8 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/pci.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/hdreg.h> | ||
30 | #include <linux/ide.h> | ||
31 | #include <linux/init.h> | ||
32 | |||
33 | #define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 | ||
34 | |||
35 | #define SCC_PATA_NAME "scc IDE" | ||
36 | |||
37 | #define TDVHSEL_MASTER 0x00000001 | ||
38 | #define TDVHSEL_SLAVE 0x00000004 | ||
39 | |||
40 | #define MODE_JCUSFEN 0x00000080 | ||
41 | |||
42 | #define CCKCTRL_ATARESET 0x00040000 | ||
43 | #define CCKCTRL_BUFCNT 0x00020000 | ||
44 | #define CCKCTRL_CRST 0x00010000 | ||
45 | #define CCKCTRL_OCLKEN 0x00000100 | ||
46 | #define CCKCTRL_ATACLKOEN 0x00000002 | ||
47 | #define CCKCTRL_LCLKEN 0x00000001 | ||
48 | |||
49 | #define QCHCD_IOS_SS 0x00000001 | ||
50 | |||
51 | #define QCHSD_STPDIAG 0x00020000 | ||
52 | |||
53 | #define INTMASK_MSK 0xD1000012 | ||
54 | #define INTSTS_SERROR 0x80000000 | ||
55 | #define INTSTS_PRERR 0x40000000 | ||
56 | #define INTSTS_RERR 0x10000000 | ||
57 | #define INTSTS_ICERR 0x01000000 | ||
58 | #define INTSTS_BMSINT 0x00000010 | ||
59 | #define INTSTS_BMHE 0x00000008 | ||
60 | #define INTSTS_IOIRQS 0x00000004 | ||
61 | #define INTSTS_INTRQ 0x00000002 | ||
62 | #define INTSTS_ACTEINT 0x00000001 | ||
63 | |||
64 | #define ECMODE_VALUE 0x01 | ||
65 | |||
66 | static struct scc_ports { | ||
67 | unsigned long ctl, dma; | ||
68 | unsigned char hwif_id; /* for removing hwif from system */ | ||
69 | } scc_ports[MAX_HWIFS]; | ||
70 | |||
71 | /* PIO transfer mode table */ | ||
72 | /* JCHST */ | ||
73 | static unsigned long JCHSTtbl[2][7] = { | ||
74 | {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
75 | {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ | ||
76 | }; | ||
77 | |||
78 | /* JCHHT */ | ||
79 | static unsigned long JCHHTtbl[2][7] = { | ||
80 | {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ | ||
81 | {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ | ||
82 | }; | ||
83 | |||
84 | /* JCHCT */ | ||
85 | static unsigned long JCHCTtbl[2][7] = { | ||
86 | {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ | ||
87 | {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ | ||
88 | }; | ||
89 | |||
90 | |||
91 | /* DMA transfer mode table */ | ||
92 | /* JCHDCTM/JCHDCTS */ | ||
93 | static unsigned long JCHDCTxtbl[2][7] = { | ||
94 | {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ | ||
95 | {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ | ||
96 | }; | ||
97 | |||
98 | /* JCSTWTM/JCSTWTS */ | ||
99 | static unsigned long JCSTWTxtbl[2][7] = { | ||
100 | {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ | ||
101 | {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
102 | }; | ||
103 | |||
104 | /* JCTSS */ | ||
105 | static unsigned long JCTSStbl[2][7] = { | ||
106 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ | ||
107 | {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ | ||
108 | }; | ||
109 | |||
110 | /* JCENVT */ | ||
111 | static unsigned long JCENVTtbl[2][7] = { | ||
112 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
113 | {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ | ||
114 | }; | ||
115 | |||
116 | /* JCACTSELS/JCACTSELM */ | ||
117 | static unsigned long JCACTSELtbl[2][7] = { | ||
118 | {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ | ||
119 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ | ||
120 | }; | ||
121 | |||
122 | |||
123 | static u8 scc_ide_inb(unsigned long port) | ||
124 | { | ||
125 | u32 data = in_be32((void*)port); | ||
126 | return (u8)data; | ||
127 | } | ||
128 | |||
129 | static u16 scc_ide_inw(unsigned long port) | ||
130 | { | ||
131 | u32 data = in_be32((void*)port); | ||
132 | return (u16)data; | ||
133 | } | ||
134 | |||
135 | static void scc_ide_insw(unsigned long port, void *addr, u32 count) | ||
136 | { | ||
137 | u16 *ptr = (u16 *)addr; | ||
138 | while (count--) { | ||
139 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void scc_ide_insl(unsigned long port, void *addr, u32 count) | ||
144 | { | ||
145 | u16 *ptr = (u16 *)addr; | ||
146 | while (count--) { | ||
147 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
148 | *ptr++ = le16_to_cpu(in_be32((void*)port)); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | static void scc_ide_outb(u8 addr, unsigned long port) | ||
153 | { | ||
154 | out_be32((void*)port, addr); | ||
155 | } | ||
156 | |||
157 | static void scc_ide_outw(u16 addr, unsigned long port) | ||
158 | { | ||
159 | out_be32((void*)port, addr); | ||
160 | } | ||
161 | |||
162 | static void | ||
163 | scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) | ||
164 | { | ||
165 | ide_hwif_t *hwif = HWIF(drive); | ||
166 | |||
167 | out_be32((void*)port, addr); | ||
168 | __asm__ __volatile__("eieio":::"memory"); | ||
169 | in_be32((void*)(hwif->dma_base + 0x01c)); | ||
170 | __asm__ __volatile__("eieio":::"memory"); | ||
171 | } | ||
172 | |||
173 | static void | ||
174 | scc_ide_outsw(unsigned long port, void *addr, u32 count) | ||
175 | { | ||
176 | u16 *ptr = (u16 *)addr; | ||
177 | while (count--) { | ||
178 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void | ||
183 | scc_ide_outsl(unsigned long port, void *addr, u32 count) | ||
184 | { | ||
185 | u16 *ptr = (u16 *)addr; | ||
186 | while (count--) { | ||
187 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
188 | out_be32((void*)port, cpu_to_le16(*ptr++)); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * scc_ratemask - Compute available modes | ||
194 | * @drive: IDE drive | ||
195 | * | ||
196 | * Compute the available speeds for the devices on the interface. | ||
197 | * Enforce UDMA33 as a limit if there is no 80pin cable present. | ||
198 | */ | ||
199 | |||
200 | static u8 scc_ratemask(ide_drive_t *drive) | ||
201 | { | ||
202 | u8 mode = 4; | ||
203 | |||
204 | if (!eighty_ninty_three(drive)) | ||
205 | mode = min(mode, (u8)1); | ||
206 | return mode; | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * scc_tuneproc - tune a drive PIO mode | ||
211 | * @drive: drive to tune | ||
212 | * @mode_wanted: the target operating mode | ||
213 | * | ||
214 | * Load the timing settings for this device mode into the | ||
215 | * controller. | ||
216 | */ | ||
217 | |||
218 | static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) | ||
219 | { | ||
220 | ide_hwif_t *hwif = HWIF(drive); | ||
221 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
222 | unsigned long ctl_base = ports->ctl; | ||
223 | unsigned long cckctrl_port = ctl_base + 0xff0; | ||
224 | unsigned long piosht_port = ctl_base + 0x000; | ||
225 | unsigned long pioct_port = ctl_base + 0x004; | ||
226 | unsigned long reg; | ||
227 | unsigned char speed = XFER_PIO_0; | ||
228 | int offset; | ||
229 | |||
230 | mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL); | ||
231 | switch (mode_wanted) { | ||
232 | case 4: | ||
233 | speed = XFER_PIO_4; | ||
234 | break; | ||
235 | case 3: | ||
236 | speed = XFER_PIO_3; | ||
237 | break; | ||
238 | case 2: | ||
239 | speed = XFER_PIO_2; | ||
240 | break; | ||
241 | case 1: | ||
242 | speed = XFER_PIO_1; | ||
243 | break; | ||
244 | case 0: | ||
245 | default: | ||
246 | speed = XFER_PIO_0; | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | reg = in_be32((void __iomem *)cckctrl_port); | ||
251 | if (reg & CCKCTRL_ATACLKOEN) { | ||
252 | offset = 1; /* 133MHz */ | ||
253 | } else { | ||
254 | offset = 0; /* 100MHz */ | ||
255 | } | ||
256 | reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; | ||
257 | out_be32((void __iomem *)piosht_port, reg); | ||
258 | reg = JCHCTtbl[offset][mode_wanted]; | ||
259 | out_be32((void __iomem *)pioct_port, reg); | ||
260 | |||
261 | ide_config_drive_speed(drive, speed); | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * scc_tune_chipset - tune a drive DMA mode | ||
266 | * @drive: Drive to set up | ||
267 | * @xferspeed: speed we want to achieve | ||
268 | * | ||
269 | * Load the timing settings for this device mode into the | ||
270 | * controller. | ||
271 | */ | ||
272 | |||
273 | static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) | ||
274 | { | ||
275 | ide_hwif_t *hwif = HWIF(drive); | ||
276 | u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed); | ||
277 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
278 | unsigned long ctl_base = ports->ctl; | ||
279 | unsigned long cckctrl_port = ctl_base + 0xff0; | ||
280 | unsigned long mdmact_port = ctl_base + 0x008; | ||
281 | unsigned long mcrcst_port = ctl_base + 0x00c; | ||
282 | unsigned long sdmact_port = ctl_base + 0x010; | ||
283 | unsigned long scrcst_port = ctl_base + 0x014; | ||
284 | unsigned long udenvt_port = ctl_base + 0x018; | ||
285 | unsigned long tdvhsel_port = ctl_base + 0x020; | ||
286 | int is_slave = (&hwif->drives[1] == drive); | ||
287 | int offset, idx; | ||
288 | unsigned long reg; | ||
289 | unsigned long jcactsel; | ||
290 | |||
291 | reg = in_be32((void __iomem *)cckctrl_port); | ||
292 | if (reg & CCKCTRL_ATACLKOEN) { | ||
293 | offset = 1; /* 133MHz */ | ||
294 | } else { | ||
295 | offset = 0; /* 100MHz */ | ||
296 | } | ||
297 | |||
298 | switch (speed) { | ||
299 | case XFER_UDMA_6: | ||
300 | idx = 6; | ||
301 | break; | ||
302 | case XFER_UDMA_5: | ||
303 | idx = 5; | ||
304 | break; | ||
305 | case XFER_UDMA_4: | ||
306 | idx = 4; | ||
307 | break; | ||
308 | case XFER_UDMA_3: | ||
309 | idx = 3; | ||
310 | break; | ||
311 | case XFER_UDMA_2: | ||
312 | idx = 2; | ||
313 | break; | ||
314 | case XFER_UDMA_1: | ||
315 | idx = 1; | ||
316 | break; | ||
317 | case XFER_UDMA_0: | ||
318 | idx = 0; | ||
319 | break; | ||
320 | default: | ||
321 | return 1; | ||
322 | } | ||
323 | |||
324 | jcactsel = JCACTSELtbl[offset][idx]; | ||
325 | if (is_slave) { | ||
326 | out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); | ||
327 | out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); | ||
328 | jcactsel = jcactsel << 2; | ||
329 | out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); | ||
330 | } else { | ||
331 | out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); | ||
332 | out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); | ||
333 | out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); | ||
334 | } | ||
335 | reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; | ||
336 | out_be32((void __iomem *)udenvt_port, reg); | ||
337 | |||
338 | return ide_config_drive_speed(drive, speed); | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * scc_config_chipset_for_dma - configure for DMA | ||
343 | * @drive: drive to configure | ||
344 | * | ||
345 | * Called by scc_config_drive_for_dma(). | ||
346 | */ | ||
347 | |||
348 | static int scc_config_chipset_for_dma(ide_drive_t *drive) | ||
349 | { | ||
350 | u8 speed = ide_dma_speed(drive, scc_ratemask(drive)); | ||
351 | |||
352 | if (!speed) | ||
353 | return 0; | ||
354 | |||
355 | if (scc_tune_chipset(drive, speed)) | ||
356 | return 0; | ||
357 | |||
358 | return ide_dma_enable(drive); | ||
359 | } | ||
360 | |||
361 | /** | ||
362 | * scc_configure_drive_for_dma - set up for DMA transfers | ||
363 | * @drive: drive we are going to set up | ||
364 | * | ||
365 | * Set up the drive for DMA, tune the controller and drive as | ||
366 | * required. | ||
367 | * If the drive isn't suitable for DMA or we hit other problems | ||
368 | * then we will drop down to PIO and set up PIO appropriately. | ||
369 | * (return 1) | ||
370 | */ | ||
371 | |||
372 | static int scc_config_drive_for_dma(ide_drive_t *drive) | ||
373 | { | ||
374 | if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) | ||
375 | return 0; | ||
376 | |||
377 | if (ide_use_fast_pio(drive)) | ||
378 | scc_tuneproc(drive, 4); | ||
379 | |||
380 | return -1; | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * scc_ide_dma_setup - begin a DMA phase | ||
385 | * @drive: target device | ||
386 | * | ||
387 | * Build an IDE DMA PRD (IDE speak for scatter gather table) | ||
388 | * and then set up the DMA transfer registers. | ||
389 | * | ||
390 | * Returns 0 on success. If a PIO fallback is required then 1 | ||
391 | * is returned. | ||
392 | */ | ||
393 | |||
394 | static int scc_dma_setup(ide_drive_t *drive) | ||
395 | { | ||
396 | ide_hwif_t *hwif = drive->hwif; | ||
397 | struct request *rq = HWGROUP(drive)->rq; | ||
398 | unsigned int reading; | ||
399 | u8 dma_stat; | ||
400 | |||
401 | if (rq_data_dir(rq)) | ||
402 | reading = 0; | ||
403 | else | ||
404 | reading = 1 << 3; | ||
405 | |||
406 | /* fall back to pio! */ | ||
407 | if (!ide_build_dmatable(drive, rq)) { | ||
408 | ide_map_sg(drive, rq); | ||
409 | return 1; | ||
410 | } | ||
411 | |||
412 | /* PRD table */ | ||
413 | out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma); | ||
414 | |||
415 | /* specify r/w */ | ||
416 | out_be32((void __iomem *)hwif->dma_command, reading); | ||
417 | |||
418 | /* read dma_status for INTR & ERROR flags */ | ||
419 | dma_stat = in_be32((void __iomem *)hwif->dma_status); | ||
420 | |||
421 | /* clear INTR & ERROR flags */ | ||
422 | out_be32((void __iomem *)hwif->dma_status, dma_stat|6); | ||
423 | drive->waiting_for_dma = 1; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | |||
428 | /** | ||
429 | * scc_ide_dma_end - Stop DMA | ||
430 | * @drive: IDE drive | ||
431 | * | ||
432 | * Check and clear INT Status register. | ||
433 | * Then call __ide_dma_end(). | ||
434 | */ | ||
435 | |||
436 | static int scc_ide_dma_end(ide_drive_t * drive) | ||
437 | { | ||
438 | ide_hwif_t *hwif = HWIF(drive); | ||
439 | unsigned long intsts_port = hwif->dma_base + 0x014; | ||
440 | u32 reg; | ||
441 | |||
442 | while (1) { | ||
443 | reg = in_be32((void __iomem *)intsts_port); | ||
444 | |||
445 | if (reg & INTSTS_SERROR) { | ||
446 | printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); | ||
447 | out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); | ||
448 | |||
449 | out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); | ||
450 | continue; | ||
451 | } | ||
452 | |||
453 | if (reg & INTSTS_PRERR) { | ||
454 | u32 maea0, maec0; | ||
455 | unsigned long ctl_base = hwif->config_data; | ||
456 | |||
457 | maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); | ||
458 | maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); | ||
459 | |||
460 | printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); | ||
461 | |||
462 | out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); | ||
463 | |||
464 | out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); | ||
465 | continue; | ||
466 | } | ||
467 | |||
468 | if (reg & INTSTS_RERR) { | ||
469 | printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); | ||
470 | out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); | ||
471 | |||
472 | out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); | ||
473 | continue; | ||
474 | } | ||
475 | |||
476 | if (reg & INTSTS_ICERR) { | ||
477 | out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); | ||
478 | |||
479 | printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); | ||
480 | out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); | ||
481 | continue; | ||
482 | } | ||
483 | |||
484 | if (reg & INTSTS_BMSINT) { | ||
485 | printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); | ||
486 | out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); | ||
487 | |||
488 | ide_do_reset(drive); | ||
489 | continue; | ||
490 | } | ||
491 | |||
492 | if (reg & INTSTS_BMHE) { | ||
493 | out_be32((void __iomem *)intsts_port, INTSTS_BMHE); | ||
494 | continue; | ||
495 | } | ||
496 | |||
497 | if (reg & INTSTS_ACTEINT) { | ||
498 | out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); | ||
499 | continue; | ||
500 | } | ||
501 | |||
502 | if (reg & INTSTS_IOIRQS) { | ||
503 | out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); | ||
504 | continue; | ||
505 | } | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | return __ide_dma_end(drive); | ||
510 | } | ||
511 | |||
512 | /* returns 1 if dma irq issued, 0 otherwise */ | ||
513 | static int scc_dma_test_irq(ide_drive_t *drive) | ||
514 | { | ||
515 | ide_hwif_t *hwif = HWIF(drive); | ||
516 | u8 dma_stat = hwif->INB(hwif->dma_status); | ||
517 | |||
518 | /* return 1 if INTR asserted */ | ||
519 | if ((dma_stat & 4) == 4) | ||
520 | return 1; | ||
521 | |||
522 | /* Workaround for PTERADD: emulate DMA_INTR when | ||
523 | * - IDE_STATUS[ERR] = 1 | ||
524 | * - INT_STATUS[INTRQ] = 1 | ||
525 | * - DMA_STATUS[IORACTA] = 1 | ||
526 | */ | ||
527 | if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT && | ||
528 | in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ && | ||
529 | dma_stat & 1) | ||
530 | return 1; | ||
531 | |||
532 | if (!drive->waiting_for_dma) | ||
533 | printk(KERN_WARNING "%s: (%s) called while not waiting\n", | ||
534 | drive->name, __FUNCTION__); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | /** | ||
539 | * setup_mmio_scc - map CTRL/BMID region | ||
540 | * @dev: PCI device we are configuring | ||
541 | * @name: device name | ||
542 | * | ||
543 | */ | ||
544 | |||
545 | static int setup_mmio_scc (struct pci_dev *dev, const char *name) | ||
546 | { | ||
547 | unsigned long ctl_base = pci_resource_start(dev, 0); | ||
548 | unsigned long dma_base = pci_resource_start(dev, 1); | ||
549 | unsigned long ctl_size = pci_resource_len(dev, 0); | ||
550 | unsigned long dma_size = pci_resource_len(dev, 1); | ||
551 | void *ctl_addr; | ||
552 | void *dma_addr; | ||
553 | int i; | ||
554 | |||
555 | for (i = 0; i < MAX_HWIFS; i++) { | ||
556 | if (scc_ports[i].ctl == 0) | ||
557 | break; | ||
558 | } | ||
559 | if (i >= MAX_HWIFS) | ||
560 | return -ENOMEM; | ||
561 | |||
562 | if (!request_mem_region(ctl_base, ctl_size, name)) { | ||
563 | printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); | ||
564 | goto fail_0; | ||
565 | } | ||
566 | |||
567 | if (!request_mem_region(dma_base, dma_size, name)) { | ||
568 | printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); | ||
569 | goto fail_1; | ||
570 | } | ||
571 | |||
572 | if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL) | ||
573 | goto fail_2; | ||
574 | |||
575 | if ((dma_addr = ioremap(dma_base, dma_size)) == NULL) | ||
576 | goto fail_3; | ||
577 | |||
578 | pci_set_master(dev); | ||
579 | scc_ports[i].ctl = (unsigned long)ctl_addr; | ||
580 | scc_ports[i].dma = (unsigned long)dma_addr; | ||
581 | pci_set_drvdata(dev, (void *) &scc_ports[i]); | ||
582 | |||
583 | return 1; | ||
584 | |||
585 | fail_3: | ||
586 | iounmap(ctl_addr); | ||
587 | fail_2: | ||
588 | release_mem_region(dma_base, dma_size); | ||
589 | fail_1: | ||
590 | release_mem_region(ctl_base, ctl_size); | ||
591 | fail_0: | ||
592 | return -ENOMEM; | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * init_setup_scc - set up an SCC PATA Controller | ||
597 | * @dev: PCI device | ||
598 | * @d: IDE PCI device | ||
599 | * | ||
600 | * Perform the initial set up for this device. | ||
601 | */ | ||
602 | |||
603 | static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d) | ||
604 | { | ||
605 | unsigned long ctl_base; | ||
606 | unsigned long dma_base; | ||
607 | unsigned long cckctrl_port; | ||
608 | unsigned long intmask_port; | ||
609 | unsigned long mode_port; | ||
610 | unsigned long ecmode_port; | ||
611 | unsigned long dma_status_port; | ||
612 | u32 reg = 0; | ||
613 | struct scc_ports *ports; | ||
614 | int rc; | ||
615 | |||
616 | rc = setup_mmio_scc(dev, d->name); | ||
617 | if (rc < 0) { | ||
618 | return rc; | ||
619 | } | ||
620 | |||
621 | ports = pci_get_drvdata(dev); | ||
622 | ctl_base = ports->ctl; | ||
623 | dma_base = ports->dma; | ||
624 | cckctrl_port = ctl_base + 0xff0; | ||
625 | intmask_port = dma_base + 0x010; | ||
626 | mode_port = ctl_base + 0x024; | ||
627 | ecmode_port = ctl_base + 0xf00; | ||
628 | dma_status_port = dma_base + 0x004; | ||
629 | |||
630 | /* controller initialization */ | ||
631 | reg = 0; | ||
632 | out_be32((void*)cckctrl_port, reg); | ||
633 | reg |= CCKCTRL_ATACLKOEN; | ||
634 | out_be32((void*)cckctrl_port, reg); | ||
635 | reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; | ||
636 | out_be32((void*)cckctrl_port, reg); | ||
637 | reg |= CCKCTRL_CRST; | ||
638 | out_be32((void*)cckctrl_port, reg); | ||
639 | |||
640 | for (;;) { | ||
641 | reg = in_be32((void*)cckctrl_port); | ||
642 | if (reg & CCKCTRL_CRST) | ||
643 | break; | ||
644 | udelay(5000); | ||
645 | } | ||
646 | |||
647 | reg |= CCKCTRL_ATARESET; | ||
648 | out_be32((void*)cckctrl_port, reg); | ||
649 | |||
650 | out_be32((void*)ecmode_port, ECMODE_VALUE); | ||
651 | out_be32((void*)mode_port, MODE_JCUSFEN); | ||
652 | out_be32((void*)intmask_port, INTMASK_MSK); | ||
653 | |||
654 | return ide_setup_pci_device(dev, d); | ||
655 | } | ||
656 | |||
657 | /** | ||
658 | * init_mmio_iops_scc - set up the iops for MMIO | ||
659 | * @hwif: interface to set up | ||
660 | * | ||
661 | */ | ||
662 | |||
663 | static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) | ||
664 | { | ||
665 | struct pci_dev *dev = hwif->pci_dev; | ||
666 | struct scc_ports *ports = pci_get_drvdata(dev); | ||
667 | unsigned long dma_base = ports->dma; | ||
668 | |||
669 | ide_set_hwifdata(hwif, ports); | ||
670 | |||
671 | hwif->INB = scc_ide_inb; | ||
672 | hwif->INW = scc_ide_inw; | ||
673 | hwif->INSW = scc_ide_insw; | ||
674 | hwif->INSL = scc_ide_insl; | ||
675 | hwif->OUTB = scc_ide_outb; | ||
676 | hwif->OUTBSYNC = scc_ide_outbsync; | ||
677 | hwif->OUTW = scc_ide_outw; | ||
678 | hwif->OUTSW = scc_ide_outsw; | ||
679 | hwif->OUTSL = scc_ide_outsl; | ||
680 | |||
681 | hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20; | ||
682 | hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24; | ||
683 | hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28; | ||
684 | hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c; | ||
685 | hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30; | ||
686 | hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34; | ||
687 | hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38; | ||
688 | hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c; | ||
689 | hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40; | ||
690 | |||
691 | hwif->irq = hwif->pci_dev->irq; | ||
692 | hwif->dma_base = dma_base; | ||
693 | hwif->config_data = ports->ctl; | ||
694 | hwif->mmio = 1; | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * init_iops_scc - set up iops | ||
699 | * @hwif: interface to set up | ||
700 | * | ||
701 | * Do the basic setup for the SCC hardware interface | ||
702 | * and then do the MMIO setup. | ||
703 | */ | ||
704 | |||
705 | static void __devinit init_iops_scc(ide_hwif_t *hwif) | ||
706 | { | ||
707 | struct pci_dev *dev = hwif->pci_dev; | ||
708 | hwif->hwif_data = NULL; | ||
709 | if (pci_get_drvdata(dev) == NULL) | ||
710 | return; | ||
711 | init_mmio_iops_scc(hwif); | ||
712 | } | ||
713 | |||
714 | /** | ||
715 | * init_hwif_scc - set up hwif | ||
716 | * @hwif: interface to set up | ||
717 | * | ||
718 | * We do the basic set up of the interface structure. The SCC | ||
719 | * requires several custom handlers so we override the default | ||
720 | * ide DMA handlers appropriately. | ||
721 | */ | ||
722 | |||
723 | static void __devinit init_hwif_scc(ide_hwif_t *hwif) | ||
724 | { | ||
725 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
726 | |||
727 | ports->hwif_id = hwif->index; | ||
728 | |||
729 | hwif->dma_command = hwif->dma_base; | ||
730 | hwif->dma_status = hwif->dma_base + 0x04; | ||
731 | hwif->dma_prdtable = hwif->dma_base + 0x08; | ||
732 | |||
733 | /* PTERADD */ | ||
734 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); | ||
735 | |||
736 | hwif->dma_setup = scc_dma_setup; | ||
737 | hwif->ide_dma_end = scc_ide_dma_end; | ||
738 | hwif->speedproc = scc_tune_chipset; | ||
739 | hwif->tuneproc = scc_tuneproc; | ||
740 | hwif->ide_dma_check = scc_config_drive_for_dma; | ||
741 | hwif->ide_dma_test_irq = scc_dma_test_irq; | ||
742 | |||
743 | hwif->drives[0].autotune = IDE_TUNE_AUTO; | ||
744 | hwif->drives[1].autotune = IDE_TUNE_AUTO; | ||
745 | |||
746 | if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) { | ||
747 | hwif->ultra_mask = 0x7f; /* 133MHz */ | ||
748 | } else { | ||
749 | hwif->ultra_mask = 0x3f; /* 100MHz */ | ||
750 | } | ||
751 | hwif->mwdma_mask = 0x00; | ||
752 | hwif->swdma_mask = 0x00; | ||
753 | hwif->atapi_dma = 1; | ||
754 | |||
755 | /* we support 80c cable only. */ | ||
756 | hwif->udma_four = 1; | ||
757 | |||
758 | hwif->autodma = 0; | ||
759 | if (!noautodma) | ||
760 | hwif->autodma = 1; | ||
761 | hwif->drives[0].autodma = hwif->autodma; | ||
762 | hwif->drives[1].autodma = hwif->autodma; | ||
763 | } | ||
764 | |||
765 | #define DECLARE_SCC_DEV(name_str) \ | ||
766 | { \ | ||
767 | .name = name_str, \ | ||
768 | .init_setup = init_setup_scc, \ | ||
769 | .init_iops = init_iops_scc, \ | ||
770 | .init_hwif = init_hwif_scc, \ | ||
771 | .channels = 1, \ | ||
772 | .autodma = AUTODMA, \ | ||
773 | .bootable = ON_BOARD, \ | ||
774 | } | ||
775 | |||
776 | static ide_pci_device_t scc_chipsets[] __devinitdata = { | ||
777 | /* 0 */ DECLARE_SCC_DEV("sccIDE"), | ||
778 | }; | ||
779 | |||
780 | /** | ||
781 | * scc_init_one - pci layer discovery entry | ||
782 | * @dev: PCI device | ||
783 | * @id: ident table entry | ||
784 | * | ||
785 | * Called by the PCI code when it finds an SCC PATA controller. | ||
786 | * We then use the IDE PCI generic helper to do most of the work. | ||
787 | */ | ||
788 | |||
789 | static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
790 | { | ||
791 | ide_pci_device_t *d = &scc_chipsets[id->driver_data]; | ||
792 | return d->init_setup(dev, d); | ||
793 | } | ||
794 | |||
795 | /** | ||
796 | * scc_remove - pci layer remove entry | ||
797 | * @dev: PCI device | ||
798 | * | ||
799 | * Called by the PCI code when it removes an SCC PATA controller. | ||
800 | */ | ||
801 | |||
802 | static void __devexit scc_remove(struct pci_dev *dev) | ||
803 | { | ||
804 | struct scc_ports *ports = pci_get_drvdata(dev); | ||
805 | ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id]; | ||
806 | unsigned long ctl_base = pci_resource_start(dev, 0); | ||
807 | unsigned long dma_base = pci_resource_start(dev, 1); | ||
808 | unsigned long ctl_size = pci_resource_len(dev, 0); | ||
809 | unsigned long dma_size = pci_resource_len(dev, 1); | ||
810 | |||
811 | if (hwif->dmatable_cpu) { | ||
812 | pci_free_consistent(hwif->pci_dev, | ||
813 | PRD_ENTRIES * PRD_BYTES, | ||
814 | hwif->dmatable_cpu, | ||
815 | hwif->dmatable_dma); | ||
816 | hwif->dmatable_cpu = NULL; | ||
817 | } | ||
818 | |||
819 | ide_unregister(hwif->index); | ||
820 | |||
821 | hwif->chipset = ide_unknown; | ||
822 | iounmap((void*)ports->dma); | ||
823 | iounmap((void*)ports->ctl); | ||
824 | release_mem_region(dma_base, dma_size); | ||
825 | release_mem_region(ctl_base, ctl_size); | ||
826 | memset(ports, 0, sizeof(*ports)); | ||
827 | } | ||
828 | |||
829 | static struct pci_device_id scc_pci_tbl[] = { | ||
830 | { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
831 | { 0, }, | ||
832 | }; | ||
833 | MODULE_DEVICE_TABLE(pci, scc_pci_tbl); | ||
834 | |||
835 | static struct pci_driver driver = { | ||
836 | .name = "SCC IDE", | ||
837 | .id_table = scc_pci_tbl, | ||
838 | .probe = scc_init_one, | ||
839 | .remove = scc_remove, | ||
840 | }; | ||
841 | |||
842 | static int scc_ide_init(void) | ||
843 | { | ||
844 | return ide_pci_register_driver(&driver); | ||
845 | } | ||
846 | |||
847 | module_init(scc_ide_init); | ||
848 | /* -- No exit code? | ||
849 | static void scc_ide_exit(void) | ||
850 | { | ||
851 | ide_pci_unregister_driver(&driver); | ||
852 | } | ||
853 | module_exit(scc_ide_exit); | ||
854 | */ | ||
855 | |||
856 | |||
857 | MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); | ||
858 | MODULE_LICENSE("GPL"); | ||