diff options
Diffstat (limited to 'drivers/ide/serverworks.c')
-rw-r--r-- | drivers/ide/serverworks.c | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c index b6554ef92716..35fb8dabb55d 100644 --- a/drivers/ide/serverworks.c +++ b/drivers/ide/serverworks.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Copyright (C) 1998-2000 Michel Aubry | 2 | * Copyright (C) 1998-2000 Michel Aubry |
3 | * Copyright (C) 1998-2000 Andrzej Krzysztofowicz | 3 | * Copyright (C) 1998-2000 Andrzej Krzysztofowicz |
4 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> |
5 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 5 | * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz |
6 | * Portions copyright (c) 2001 Sun Microsystems | 6 | * Portions copyright (c) 2001 Sun Microsystems |
7 | * | 7 | * |
8 | * | 8 | * |
@@ -52,8 +52,6 @@ static const char *svwks_bad_ata100[] = { | |||
52 | NULL | 52 | NULL |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static struct pci_dev *isa_dev; | ||
56 | |||
57 | static int check_in_drive_lists (ide_drive_t *drive, const char **list) | 55 | static int check_in_drive_lists (ide_drive_t *drive, const char **list) |
58 | { | 56 | { |
59 | char *m = (char *)&drive->id[ATA_ID_PROD]; | 57 | char *m = (char *)&drive->id[ATA_ID_PROD]; |
@@ -67,26 +65,14 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list) | |||
67 | static u8 svwks_udma_filter(ide_drive_t *drive) | 65 | static u8 svwks_udma_filter(ide_drive_t *drive) |
68 | { | 66 | { |
69 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | 67 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); |
70 | u8 mask = 0; | ||
71 | 68 | ||
72 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) | 69 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) { |
73 | return 0x1f; | 70 | return 0x1f; |
74 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | ||
75 | u32 reg = 0; | ||
76 | if (isa_dev) | ||
77 | pci_read_config_dword(isa_dev, 0x64, ®); | ||
78 | |||
79 | /* | ||
80 | * Don't enable UDMA on disk devices for the moment | ||
81 | */ | ||
82 | if(drive->media == ide_disk) | ||
83 | return 0; | ||
84 | /* Check the OSB4 DMA33 enable bit */ | ||
85 | return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0; | ||
86 | } else if (dev->revision < SVWKS_CSB5_REVISION_NEW) { | 71 | } else if (dev->revision < SVWKS_CSB5_REVISION_NEW) { |
87 | return 0x07; | 72 | return 0x07; |
88 | } else if (dev->revision >= SVWKS_CSB5_REVISION_NEW) { | 73 | } else { |
89 | u8 btr = 0, mode; | 74 | u8 btr = 0, mode, mask; |
75 | |||
90 | pci_read_config_byte(dev, 0x5A, &btr); | 76 | pci_read_config_byte(dev, 0x5A, &btr); |
91 | mode = btr & 0x3; | 77 | mode = btr & 0x3; |
92 | 78 | ||
@@ -101,13 +87,9 @@ static u8 svwks_udma_filter(ide_drive_t *drive) | |||
101 | case 1: mask = 0x07; break; | 87 | case 1: mask = 0x07; break; |
102 | default: mask = 0x00; break; | 88 | default: mask = 0x00; break; |
103 | } | 89 | } |
104 | } | ||
105 | if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || | ||
106 | (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && | ||
107 | (!(PCI_FUNC(dev->devfn) & 1))) | ||
108 | mask = 0x1f; | ||
109 | 90 | ||
110 | return mask; | 91 | return mask; |
92 | } | ||
111 | } | 93 | } |
112 | 94 | ||
113 | static u8 svwks_csb_check (struct pci_dev *dev) | 95 | static u8 svwks_csb_check (struct pci_dev *dev) |
@@ -124,12 +106,13 @@ static u8 svwks_csb_check (struct pci_dev *dev) | |||
124 | return 0; | 106 | return 0; |
125 | } | 107 | } |
126 | 108 | ||
127 | static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio) | 109 | static void svwks_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
128 | { | 110 | { |
129 | static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; | 111 | static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; |
130 | static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; | 112 | static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; |
131 | 113 | ||
132 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | 114 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
115 | const u8 pio = drive->pio_mode - XFER_PIO_0; | ||
133 | 116 | ||
134 | pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]); | 117 | pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]); |
135 | 118 | ||
@@ -145,14 +128,14 @@ static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
145 | } | 128 | } |
146 | } | 129 | } |
147 | 130 | ||
148 | static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) | 131 | static void svwks_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
149 | { | 132 | { |
150 | static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; | 133 | static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; |
151 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; | 134 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; |
152 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; | 135 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; |
153 | 136 | ||
154 | ide_hwif_t *hwif = drive->hwif; | ||
155 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 137 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
138 | const u8 speed = drive->dma_mode; | ||
156 | u8 unit = drive->dn & 1; | 139 | u8 unit = drive->dn & 1; |
157 | 140 | ||
158 | u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; | 141 | u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; |
@@ -185,8 +168,9 @@ static int init_chipset_svwks(struct pci_dev *dev) | |||
185 | 168 | ||
186 | /* OSB4 : South Bridge and IDE */ | 169 | /* OSB4 : South Bridge and IDE */ |
187 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | 170 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { |
188 | isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, | 171 | struct pci_dev *isa_dev = |
189 | PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); | 172 | pci_get_device(PCI_VENDOR_ID_SERVERWORKS, |
173 | PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); | ||
190 | if (isa_dev) { | 174 | if (isa_dev) { |
191 | pci_read_config_dword(isa_dev, 0x64, ®); | 175 | pci_read_config_dword(isa_dev, 0x64, ®); |
192 | reg &= ~0x00002000; /* disable 600ns interrupt mask */ | 176 | reg &= ~0x00002000; /* disable 600ns interrupt mask */ |
@@ -195,6 +179,7 @@ static int init_chipset_svwks(struct pci_dev *dev) | |||
195 | "enabled.\n", pci_name(dev)); | 179 | "enabled.\n", pci_name(dev)); |
196 | reg |= 0x00004000; /* enable UDMA/33 support */ | 180 | reg |= 0x00004000; /* enable UDMA/33 support */ |
197 | pci_write_config_dword(isa_dev, 0x64, reg); | 181 | pci_write_config_dword(isa_dev, 0x64, reg); |
182 | pci_dev_put(isa_dev); | ||
198 | } | 183 | } |
199 | } | 184 | } |
200 | 185 | ||
@@ -343,7 +328,6 @@ static u8 svwks_cable_detect(ide_hwif_t *hwif) | |||
343 | static const struct ide_port_ops osb4_port_ops = { | 328 | static const struct ide_port_ops osb4_port_ops = { |
344 | .set_pio_mode = svwks_set_pio_mode, | 329 | .set_pio_mode = svwks_set_pio_mode, |
345 | .set_dma_mode = svwks_set_dma_mode, | 330 | .set_dma_mode = svwks_set_dma_mode, |
346 | .udma_filter = svwks_udma_filter, | ||
347 | }; | 331 | }; |
348 | 332 | ||
349 | static const struct ide_port_ops svwks_port_ops = { | 333 | static const struct ide_port_ops svwks_port_ops = { |
@@ -460,6 +444,6 @@ static void __exit svwks_ide_exit(void) | |||
460 | module_init(svwks_ide_init); | 444 | module_init(svwks_ide_init); |
461 | module_exit(svwks_ide_exit); | 445 | module_exit(svwks_ide_exit); |
462 | 446 | ||
463 | MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick"); | 447 | MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick, Bartlomiej Zolnierkiewicz"); |
464 | MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE"); | 448 | MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE"); |
465 | MODULE_LICENSE("GPL"); | 449 | MODULE_LICENSE("GPL"); |