]>
Commit | Line | Data |
---|---|---|
18fc453c | 1 | diff -Nur linux-2.4.19/drivers/ide/Config.in linux-2.4.19.new/drivers/ide/Config.in |
2 | --- linux-2.4.19/drivers/ide/Config.in Sat Aug 3 02:39:44 2002 | |
3 | +++ linux-2.4.19.new/drivers/ide/Config.in Wed Nov 13 09:49:39 2002 | |
4 | @@ -65,14 +65,14 @@ | |
5 | dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 | |
6 | dep_bool ' AMD Viper support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI | |
7 | dep_mbool ' AMD Viper ATA-66 Override (WIP)' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX $CONFIG_IDEDMA_PCI_WIP | |
8 | - dep_bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI | |
9 | + dep_bool ' CMD64X and CMD680 chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI | |
10 | dep_bool ' CMD680 chipset tuning support' CONFIG_BLK_DEV_CMD680 $CONFIG_BLK_DEV_CMD64X | |
11 | dep_bool ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI | |
12 | dep_bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI | |
13 | dep_bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI | |
14 | dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP | |
15 | dep_bool ' HPT366/368/370 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI | |
16 | - if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then | |
17 | + if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" -o "$CONFIG_MIPS" = "y" ]; then | |
18 | dep_mbool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI | |
19 | dep_mbool ' PIIXn Tuning support' CONFIG_PIIX_TUNING $CONFIG_BLK_DEV_PIIX $CONFIG_IDEDMA_PCI_AUTO | |
20 | fi | |
21 | @@ -108,7 +108,7 @@ | |
22 | fi | |
23 | fi | |
24 | if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then | |
25 | - bool ' SWARM onboard IDE support' CONFIG_BLK_DEV_IDE_SWARM | |
26 | + bool ' Broadcom SiByte onboard IDE support' CONFIG_BLK_DEV_IDE_SIBYTE | |
27 | fi | |
28 | if [ "$CONFIG_ARCH_ACORN" = "y" ]; then | |
29 | dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN | |
30 | @@ -144,7 +144,8 @@ | |
31 | EXT_DIRECT CONFIG_IDE_EXT_DIRECT" 8xx_PCCARD | |
32 | fi | |
33 | ||
34 | - bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS | |
35 | + # no isa -> no vlb | |
36 | + dep_bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS $CONFIG_ISA | |
37 | if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then | |
38 | comment 'Note: most of these also require special kernel boot parameters' | |
39 | bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES | |
40 | @@ -209,8 +210,8 @@ | |
41 | define_bool CONFIG_BLK_DEV_IDE_MODES n | |
42 | fi | |
43 | ||
44 | -dep_tristate 'Support for IDE Raid controllers' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL | |
45 | -dep_tristate ' Support Promise software RAID (Fasttrak(tm))' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID | |
46 | -dep_tristate ' Highpoint 370 software RAID' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID | |
47 | +dep_tristate 'Support for IDE Raid controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL | |
48 | +dep_tristate ' Support Promise software RAID (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID | |
49 | +dep_tristate ' Highpoint 370 software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID | |
50 | ||
51 | endmenu | |
52 | diff -Nur linux-2.4.19/drivers/ide/Makefile linux-2.4.19.new/drivers/ide/Makefile | |
53 | --- linux-2.4.19/drivers/ide/Makefile Sat Aug 3 02:39:44 2002 | |
54 | +++ linux-2.4.19.new/drivers/ide/Makefile Wed Nov 13 09:49:39 2002 | |
55 | @@ -49,7 +49,7 @@ | |
56 | ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o | |
57 | ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o | |
58 | ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o | |
59 | -ide-obj-$(CONFIG_BLK_DEV_IDE_SWARM) += ide-swarm.o | |
60 | +ide-obj-$(CONFIG_BLK_DEV_IDE_SIBYTE) += ide-sibyte.o | |
61 | ide-obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o | |
62 | ide-obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o | |
63 | ide-obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o | |
64 | diff -Nur linux-2.4.19/drivers/ide/ide-cd.c linux-2.4.19.new/drivers/ide/ide-cd.c | |
65 | --- linux-2.4.19/drivers/ide/ide-cd.c Sat Aug 3 02:39:44 2002 | |
66 | +++ linux-2.4.19.new/drivers/ide/ide-cd.c Wed Nov 13 09:49:39 2002 | |
67 | @@ -2194,6 +2194,8 @@ | |
68 | layer. the packet must be complete, as we do not | |
69 | touch it at all. */ | |
70 | memset(&pc, 0, sizeof(pc)); | |
71 | + if (cgc->sense) | |
72 | + memset(cgc->sense, 0, sizeof(struct request_sense)); | |
73 | memcpy(pc.c, cgc->cmd, CDROM_PACKET_SIZE); | |
74 | pc.buffer = cgc->buffer; | |
75 | pc.buflen = cgc->buflen; | |
76 | diff -Nur linux-2.4.19/drivers/ide/ide-cs.c linux-2.4.19.new/drivers/ide/ide-cs.c | |
77 | --- linux-2.4.19/drivers/ide/ide-cs.c Sat Aug 3 02:39:44 2002 | |
78 | +++ linux-2.4.19.new/drivers/ide/ide-cs.c Wed Nov 13 09:49:39 2002 | |
79 | @@ -15,7 +15,7 @@ | |
80 | rights and limitations under the License. | |
81 | ||
82 | The initial developer of the original code is David A. Hinds | |
83 | - <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds | |
84 | + <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | |
85 | are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | |
86 | ||
87 | Alternatively, the contents of this file may be used under the | |
88 | diff -Nur linux-2.4.19/drivers/ide/ide-disk.c linux-2.4.19.new/drivers/ide/ide-disk.c | |
89 | --- linux-2.4.19/drivers/ide/ide-disk.c Sat Aug 3 02:39:44 2002 | |
90 | +++ linux-2.4.19.new/drivers/ide/ide-disk.c Wed Nov 13 09:49:39 2002 | |
91 | @@ -29,6 +29,7 @@ | |
92 | * Version 1.10 request queue changes, Ultra DMA 100 | |
93 | * Version 1.11 added 48-bit lba | |
94 | * Version 1.12 adding taskfile io access method | |
95 | + * Highmem I/O support, Jens Axboe <axboe@suse.de> | |
96 | */ | |
97 | ||
98 | #define IDEDISK_VERSION "1.12" | |
99 | @@ -158,7 +159,9 @@ | |
100 | byte stat; | |
101 | int i; | |
102 | unsigned int msect, nsect; | |
103 | + unsigned long flags; | |
104 | struct request *rq; | |
105 | + char *to; | |
106 | ||
107 | /* new way for dealing with premature shared PCI interrupts */ | |
108 | if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { | |
109 | @@ -169,8 +172,8 @@ | |
110 | ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); | |
111 | return ide_started; | |
112 | } | |
113 | + | |
114 | msect = drive->mult_count; | |
115 | - | |
116 | read_next: | |
117 | rq = HWGROUP(drive)->rq; | |
118 | if (msect) { | |
119 | @@ -179,14 +182,15 @@ | |
120 | msect -= nsect; | |
121 | } else | |
122 | nsect = 1; | |
123 | - idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); | |
124 | + to = ide_map_buffer(rq, &flags); | |
125 | + idedisk_input_data(drive, to, nsect * SECTOR_WORDS); | |
126 | #ifdef DEBUG | |
127 | printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", | |
128 | drive->name, rq->sector, rq->sector+nsect-1, | |
129 | (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect); | |
130 | #endif | |
131 | + ide_unmap_buffer(to, &flags); | |
132 | rq->sector += nsect; | |
133 | - rq->buffer += nsect<<9; | |
134 | rq->errors = 0; | |
135 | i = (rq->nr_sectors -= nsect); | |
136 | if (((long)(rq->current_nr_sectors -= nsect)) <= 0) | |
137 | @@ -220,14 +224,16 @@ | |
138 | #endif | |
139 | if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) { | |
140 | rq->sector++; | |
141 | - rq->buffer += 512; | |
142 | rq->errors = 0; | |
143 | i = --rq->nr_sectors; | |
144 | --rq->current_nr_sectors; | |
145 | if (((long)rq->current_nr_sectors) <= 0) | |
146 | ide_end_request(1, hwgroup); | |
147 | if (i > 0) { | |
148 | - idedisk_output_data (drive, rq->buffer, SECTOR_WORDS); | |
149 | + unsigned long flags; | |
150 | + char *to = ide_map_buffer(rq, &flags); | |
151 | + idedisk_output_data (drive, to, SECTOR_WORDS); | |
152 | + ide_unmap_buffer(to, &flags); | |
153 | ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); | |
154 | return ide_started; | |
155 | } | |
156 | @@ -257,14 +263,14 @@ | |
157 | do { | |
158 | char *buffer; | |
159 | int nsect = rq->current_nr_sectors; | |
160 | - | |
161 | + unsigned long flags; | |
162 | + | |
163 | if (nsect > mcount) | |
164 | nsect = mcount; | |
165 | mcount -= nsect; | |
166 | - buffer = rq->buffer; | |
167 | ||
168 | + buffer = ide_map_buffer(rq, &flags); | |
169 | rq->sector += nsect; | |
170 | - rq->buffer += nsect << 9; | |
171 | rq->nr_sectors -= nsect; | |
172 | rq->current_nr_sectors -= nsect; | |
173 | ||
174 | @@ -278,7 +284,7 @@ | |
175 | } else { | |
176 | rq->bh = bh; | |
177 | rq->current_nr_sectors = bh->b_size >> 9; | |
178 | - rq->buffer = bh->b_data; | |
179 | + rq->hard_cur_sectors = rq->current_nr_sectors; | |
180 | } | |
181 | } | |
182 | ||
183 | @@ -287,6 +293,7 @@ | |
184 | * re-entering us on the last transfer. | |
185 | */ | |
186 | idedisk_output_data(drive, buffer, nsect<<7); | |
187 | + ide_unmap_buffer(buffer, &flags); | |
188 | } while (mcount); | |
189 | ||
190 | return 0; | |
191 | @@ -695,8 +702,11 @@ | |
192 | return ide_stopped; | |
193 | } | |
194 | } else { | |
195 | + unsigned long flags; | |
196 | + char *buffer = ide_map_buffer(rq, &flags); | |
197 | ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); | |
198 | - idedisk_output_data(drive, rq->buffer, SECTOR_WORDS); | |
199 | + idedisk_output_data(drive, buffer, SECTOR_WORDS); | |
200 | + ide_unmap_buffer(buffer, &flags); | |
201 | } | |
202 | return ide_started; | |
203 | } | |
204 | diff -Nur linux-2.4.19/drivers/ide/ide-dma.c linux-2.4.19.new/drivers/ide/ide-dma.c | |
205 | --- linux-2.4.19/drivers/ide/ide-dma.c Sat Aug 3 02:39:44 2002 | |
206 | +++ linux-2.4.19.new/drivers/ide/ide-dma.c Wed Nov 13 09:49:39 2002 | |
207 | @@ -252,33 +252,53 @@ | |
208 | { | |
209 | struct buffer_head *bh; | |
210 | struct scatterlist *sg = hwif->sg_table; | |
211 | + unsigned long lastdataend = ~0UL; | |
212 | int nents = 0; | |
213 | ||
214 | if (hwif->sg_dma_active) | |
215 | BUG(); | |
216 | - | |
217 | + | |
218 | if (rq->cmd == READ) | |
219 | hwif->sg_dma_direction = PCI_DMA_FROMDEVICE; | |
220 | else | |
221 | hwif->sg_dma_direction = PCI_DMA_TODEVICE; | |
222 | + | |
223 | bh = rq->bh; | |
224 | do { | |
225 | - unsigned char *virt_addr = bh->b_data; | |
226 | - unsigned int size = bh->b_size; | |
227 | + struct scatterlist *sge; | |
228 | + | |
229 | + /* | |
230 | + * continue segment from before? | |
231 | + */ | |
232 | + if (bh_phys(bh) == lastdataend) { | |
233 | + sg[nents - 1].length += bh->b_size; | |
234 | + lastdataend += bh->b_size; | |
235 | + continue; | |
236 | + } | |
237 | ||
238 | + /* | |
239 | + * start new segment | |
240 | + */ | |
241 | if (nents >= PRD_ENTRIES) | |
242 | return 0; | |
243 | ||
244 | - while ((bh = bh->b_reqnext) != NULL) { | |
245 | - if ((virt_addr + size) != (unsigned char *) bh->b_data) | |
246 | - break; | |
247 | - size += bh->b_size; | |
248 | + sge = &sg[nents]; | |
249 | + memset(sge, 0, sizeof(*sge)); | |
250 | + | |
251 | + if (bh->b_page) { | |
252 | + sge->page = bh->b_page; | |
253 | + sge->offset = bh_offset(bh); | |
254 | + } else { | |
255 | + if (((unsigned long) bh->b_data) < PAGE_SIZE) | |
256 | + BUG(); | |
257 | + | |
258 | + sge->address = bh->b_data; | |
259 | } | |
260 | - memset(&sg[nents], 0, sizeof(*sg)); | |
261 | - sg[nents].address = virt_addr; | |
262 | - sg[nents].length = size; | |
263 | + | |
264 | + sge->length = bh->b_size; | |
265 | + lastdataend = bh_phys(bh) + bh->b_size; | |
266 | nents++; | |
267 | - } while (bh != NULL); | |
268 | + } while ((bh = bh->b_reqnext) != NULL); | |
269 | ||
270 | return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); | |
271 | } | |
272 | @@ -340,7 +360,7 @@ | |
273 | return 0; | |
274 | ||
275 | sg = HWIF(drive)->sg_table; | |
276 | - while (i && sg_dma_len(sg)) { | |
277 | + while (i) { | |
278 | u32 cur_addr; | |
279 | u32 cur_len; | |
280 | ||
281 | @@ -354,36 +374,35 @@ | |
282 | */ | |
283 | ||
284 | while (cur_len) { | |
285 | - if (count++ >= PRD_ENTRIES) { | |
286 | - printk("%s: DMA table too small\n", drive->name); | |
287 | - goto use_pio_instead; | |
288 | - } else { | |
289 | - u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); | |
290 | - | |
291 | - if (bcount > cur_len) | |
292 | - bcount = cur_len; | |
293 | - *table++ = cpu_to_le32(cur_addr); | |
294 | - xcount = bcount & 0xffff; | |
295 | - if (is_trm290_chipset) | |
296 | - xcount = ((xcount >> 2) - 1) << 16; | |
297 | - if (xcount == 0x0000) { | |
298 | - /* | |
299 | - * Most chipsets correctly interpret a length of 0x0000 as 64KB, | |
300 | - * but at least one (e.g. CS5530) misinterprets it as zero (!). | |
301 | - * So here we break the 64KB entry into two 32KB entries instead. | |
302 | - */ | |
303 | - if (count++ >= PRD_ENTRIES) { | |
304 | - printk("%s: DMA table too small\n", drive->name); | |
305 | - goto use_pio_instead; | |
306 | - } | |
307 | - *table++ = cpu_to_le32(0x8000); | |
308 | - *table++ = cpu_to_le32(cur_addr + 0x8000); | |
309 | - xcount = 0x8000; | |
310 | - } | |
311 | - *table++ = cpu_to_le32(xcount); | |
312 | - cur_addr += bcount; | |
313 | - cur_len -= bcount; | |
314 | + u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); | |
315 | + | |
316 | + if (count++ >= PRD_ENTRIES) | |
317 | + BUG(); | |
318 | + | |
319 | + if (bcount > cur_len) | |
320 | + bcount = cur_len; | |
321 | + *table++ = cpu_to_le32(cur_addr); | |
322 | + xcount = bcount & 0xffff; | |
323 | + if (is_trm290_chipset) | |
324 | + xcount = ((xcount >> 2) - 1) << 16; | |
325 | + if (xcount == 0x0000) { | |
326 | + /* | |
327 | + * Most chipsets correctly interpret a length | |
328 | + * of 0x0000 as 64KB, but at least one | |
329 | + * (e.g. CS5530) misinterprets it as zero (!). | |
330 | + * So here we break the 64KB entry into two | |
331 | + * 32KB entries instead. | |
332 | + */ | |
333 | + if (count++ >= PRD_ENTRIES) | |
334 | + goto use_pio_instead; | |
335 | + | |
336 | + *table++ = cpu_to_le32(0x8000); | |
337 | + *table++ = cpu_to_le32(cur_addr + 0x8000); | |
338 | + xcount = 0x8000; | |
339 | } | |
340 | + *table++ = cpu_to_le32(xcount); | |
341 | + cur_addr += bcount; | |
342 | + cur_len -= bcount; | |
343 | } | |
344 | ||
345 | sg++; | |
346 | @@ -584,6 +603,23 @@ | |
347 | } | |
348 | #endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
349 | ||
350 | +static inline void ide_toggle_bounce(ide_drive_t *drive, int on) | |
351 | +{ | |
352 | + dma64_addr_t addr = BLK_BOUNCE_HIGH; | |
353 | + | |
354 | + if (HWIF(drive)->no_highio || HWIF(drive)->pci_dev == NULL) | |
355 | + return; | |
356 | + | |
357 | + if (on && drive->media == ide_disk) { | |
358 | + if (!PCI_DMA_BUS_IS_PHYS) | |
359 | + addr = BLK_BOUNCE_ANY; | |
360 | + else | |
361 | + addr = HWIF(drive)->pci_dev->dma_mask; | |
362 | + } | |
363 | + | |
364 | + blk_queue_bounce_limit(&drive->queue, addr); | |
365 | +} | |
366 | + | |
367 | /* | |
368 | * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. | |
369 | * | |
370 | @@ -606,18 +642,20 @@ | |
371 | ide_hwif_t *hwif = HWIF(drive); | |
372 | unsigned long dma_base = hwif->dma_base; | |
373 | byte unit = (drive->select.b.unit & 0x01); | |
374 | - unsigned int count, reading = 0; | |
375 | + unsigned int count, reading = 0, set_high = 1; | |
376 | byte dma_stat; | |
377 | ||
378 | switch (func) { | |
379 | case ide_dma_off: | |
380 | printk("%s: DMA disabled\n", drive->name); | |
381 | case ide_dma_off_quietly: | |
382 | + set_high = 0; | |
383 | outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
384 | case ide_dma_on: | |
385 | drive->using_dma = (func == ide_dma_on); | |
386 | if (drive->using_dma) | |
387 | outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
388 | + ide_toggle_bounce(drive, set_high); | |
389 | return 0; | |
390 | case ide_dma_check: | |
391 | return config_drive_for_dma (drive); | |
392 | @@ -759,8 +797,8 @@ | |
393 | request_region(dma_base, num_ports, hwif->name); | |
394 | hwif->dma_base = dma_base; | |
395 | hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, | |
396 | - PRD_ENTRIES * PRD_BYTES, | |
397 | - &hwif->dmatable_dma); | |
398 | + PRD_ENTRIES * PRD_BYTES, | |
399 | + &hwif->dmatable_dma); | |
400 | if (hwif->dmatable_cpu == NULL) | |
401 | goto dma_alloc_failure; | |
402 | ||
403 | diff -Nur linux-2.4.19/drivers/ide/ide-geometry.c linux-2.4.19.new/drivers/ide/ide-geometry.c | |
404 | --- linux-2.4.19/drivers/ide/ide-geometry.c Sat Aug 3 02:39:44 2002 | |
405 | +++ linux-2.4.19.new/drivers/ide/ide-geometry.c Wed Nov 13 09:49:39 2002 | |
406 | @@ -32,7 +32,7 @@ | |
407 | * for us during initialization. I have the necessary docs -- any takers? -ml | |
408 | */ | |
409 | /* | |
410 | - * I did this, but it doesnt work - there is no reasonable way to find the | |
411 | + * I did this, but it doesn't work - there is no reasonable way to find the | |
412 | * correspondence between the BIOS numbering of the disks and the Linux | |
413 | * numbering. -aeb | |
414 | * | |
415 | diff -Nur linux-2.4.19/drivers/ide/ide-pci.c linux-2.4.19.new/drivers/ide/ide-pci.c | |
416 | --- linux-2.4.19/drivers/ide/ide-pci.c Sat Aug 3 02:39:44 2002 | |
417 | +++ linux-2.4.19.new/drivers/ide/ide-pci.c Wed Nov 13 09:49:39 2002 | |
418 | @@ -405,7 +405,7 @@ | |
419 | #ifndef CONFIG_PDC202XX_FORCE | |
420 | {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 16 }, | |
421 | {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
422 | - {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 48 }, | |
423 | + {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
424 | {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
425 | #else /* !CONFIG_PDC202XX_FORCE */ | |
426 | {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, | |
427 | @@ -623,8 +623,12 @@ | |
428 | } | |
429 | ||
430 | if (pci_enable_device(dev)) { | |
431 | - printk(KERN_WARNING "%s: (ide_setup_pci_device:) Could not enable device.\n", d->name); | |
432 | - return; | |
433 | + if(pci_enable_device_bars(dev, 1<<4)) | |
434 | + { | |
435 | + printk(KERN_WARNING "%s: (ide_setup_pci_device:) Could not enable device.\n", d->name); | |
436 | + return; | |
437 | + } | |
438 | + printk(KERN_INFO "%s: BIOS setup was incomplete.\n", d->name); | |
439 | } | |
440 | ||
441 | check_if_enabled: | |
442 | @@ -669,18 +673,27 @@ | |
443 | */ | |
444 | pciirq = dev->irq; | |
445 | ||
446 | -#ifdef CONFIG_PDC202XX_FORCE | |
447 | - if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) { | |
448 | - /* | |
449 | - * By rights we want to ignore Promise FastTrak and SuperTrak | |
450 | - * series here, those use own driver. | |
451 | + if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) | |
452 | + { | |
453 | + /* By rights we want to ignore these, but the Promise Fastrak | |
454 | + * people have some strange ideas about proprietary so we have | |
455 | + * to act otherwise on those. The supertrak however we need | |
456 | + * to skip | |
457 | */ | |
458 | - if (dev->vendor == PCI_VENDOR_ID_PROMISE) { | |
459 | - printk(KERN_INFO "ide: Skipping Promise RAID controller.\n"); | |
460 | - return; | |
461 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) | |
462 | + { | |
463 | + printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n"); | |
464 | + if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL && | |
465 | + dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) | |
466 | + { | |
467 | + printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n"); | |
468 | + return; | |
469 | + } | |
470 | } | |
471 | + /* Its attached to something else, just a random bridge. | |
472 | + Suspect a fastrak and fall through */ | |
473 | } | |
474 | -#endif /* CONFIG_PDC202XX_FORCE */ | |
475 | + | |
476 | if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { | |
477 | printk("%s: not 100%% native mode: will probe irqs later\n", d->name); | |
478 | /* | |
479 | diff -Nur linux-2.4.19/drivers/ide/ide-pmac.c linux-2.4.19.new/drivers/ide/ide-pmac.c | |
480 | --- linux-2.4.19/drivers/ide/ide-pmac.c Sat Aug 3 02:39:44 2002 | |
481 | +++ linux-2.4.19.new/drivers/ide/ide-pmac.c Wed Nov 13 09:49:39 2002 | |
482 | @@ -114,8 +114,7 @@ | |
483 | * well, despite a comment that would lead to think it has a | |
484 | * min value of 45ns. | |
485 | * Apple also add 60ns to the write data setup (or cycle time ?) on | |
486 | - * reads. I can't explain that, I tried it and it broke everything | |
487 | - * here. | |
488 | + * reads. | |
489 | */ | |
490 | #define TR_66_UDMA_MASK 0xfff00000 | |
491 | #define TR_66_UDMA_EN 0x00100000 /* Enable Ultra mode for DMA */ | |
492 | @@ -401,7 +400,6 @@ | |
493 | pmac_ide_do_setfeature(ide_drive_t *drive, byte command) | |
494 | { | |
495 | int result = 1; | |
496 | - unsigned long flags; | |
497 | ide_hwif_t *hwif = HWIF(drive); | |
498 | ||
499 | disable_irq(hwif->irq); /* disable_irq_nosync ?? */ | |
500 | @@ -420,10 +418,7 @@ | |
501 | OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); | |
502 | OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); | |
503 | udelay(1); | |
504 | - __save_flags(flags); /* local CPU only */ | |
505 | - ide__sti(); /* local CPU only -- for jiffies */ | |
506 | result = wait_for_ready(drive); | |
507 | - __restore_flags(flags); /* local CPU only */ | |
508 | OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
509 | if (result) | |
510 | printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n"); | |
511 | @@ -956,6 +951,8 @@ | |
512 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay; | |
513 | hwif->udma_four = (pmhw->kind == controller_kl_ata4_80); | |
514 | hwif->pci_dev = pdev; | |
515 | + hwif->drives[0].unmask = 1; | |
516 | + hwif->drives[1].unmask = 1; | |
517 | #ifdef CONFIG_PMAC_PBOOK | |
518 | if (in_bay && check_media_bay_by_base(base, MB_CD) == 0) | |
519 | hwif->noprobe = 0; | |
520 | @@ -1032,33 +1029,48 @@ | |
521 | struct pmac_ide_hwif *pmif = &pmac_ide[ix]; | |
522 | struct buffer_head *bh; | |
523 | struct scatterlist *sg = pmif->sg_table; | |
524 | + unsigned long lastdataend = ~0UL; | |
525 | int nents = 0; | |
526 | ||
527 | if (hwif->sg_dma_active) | |
528 | BUG(); | |
529 | - | |
530 | + | |
531 | if (rq->cmd == READ) | |
532 | pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; | |
533 | else | |
534 | pmif->sg_dma_direction = PCI_DMA_TODEVICE; | |
535 | + | |
536 | bh = rq->bh; | |
537 | do { | |
538 | - unsigned char *virt_addr = bh->b_data; | |
539 | + struct scatterlist *sge; | |
540 | unsigned int size = bh->b_size; | |
541 | ||
542 | + /* continue segment from before? */ | |
543 | + if (bh_phys(bh) == lastdataend) { | |
544 | + sg[nents-1].length += size; | |
545 | + lastdataend += size; | |
546 | + continue; | |
547 | + } | |
548 | + | |
549 | + /* start new segment */ | |
550 | if (nents >= MAX_DCMDS) | |
551 | return 0; | |
552 | ||
553 | - while ((bh = bh->b_reqnext) != NULL) { | |
554 | - if ((virt_addr + size) != (unsigned char *) bh->b_data) | |
555 | - break; | |
556 | - size += bh->b_size; | |
557 | + sge = &sg[nents]; | |
558 | + memset(sge, 0, sizeof(*sge)); | |
559 | + | |
560 | + if (bh->b_page) { | |
561 | + sge->page = bh->b_page; | |
562 | + sge->offset = bh_offset(bh); | |
563 | + } else { | |
564 | + if ((unsigned long)bh->b_data < PAGE_SIZE) | |
565 | + BUG(); | |
566 | + sge->address = bh->b_data; | |
567 | } | |
568 | - memset(&sg[nents], 0, sizeof(*sg)); | |
569 | - sg[nents].address = virt_addr; | |
570 | - sg[nents].length = size; | |
571 | + sge->length = size; | |
572 | + lastdataend = bh_phys(bh) + size; | |
573 | nents++; | |
574 | - } while (bh != NULL); | |
575 | + } while ((bh = bh->b_reqnext) != NULL); | |
576 | ||
577 | return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction); | |
578 | } | |
579 | @@ -1330,6 +1342,23 @@ | |
580 | return 0; | |
581 | } | |
582 | ||
583 | +static inline void pmac_ide_toggle_bounce(ide_drive_t *drive, int on) | |
584 | +{ | |
585 | + dma64_addr_t addr = BLK_BOUNCE_HIGH; | |
586 | + | |
587 | + if (HWIF(drive)->no_highio || HWIF(drive)->pci_dev == NULL) | |
588 | + return; | |
589 | + | |
590 | + if (on && drive->media == ide_disk) { | |
591 | + if (!PCI_DMA_BUS_IS_PHYS) | |
592 | + addr = BLK_BOUNCE_ANY; | |
593 | + else | |
594 | + addr = HWIF(drive)->pci_dev->dma_mask; | |
595 | + } | |
596 | + | |
597 | + blk_queue_bounce_limit(&drive->queue, addr); | |
598 | +} | |
599 | + | |
600 | static int __pmac | |
601 | pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
602 | { | |
603 | @@ -1354,10 +1383,13 @@ | |
604 | printk(KERN_INFO "%s: DMA disabled\n", drive->name); | |
605 | case ide_dma_off_quietly: | |
606 | drive->using_dma = 0; | |
607 | + pmac_ide_toggle_bounce(drive, 0); | |
608 | break; | |
609 | case ide_dma_on: | |
610 | case ide_dma_check: | |
611 | pmac_ide_check_dma(drive); | |
612 | + if (drive->using_dma) | |
613 | + pmac_ide_toggle_bounce(drive, 1); | |
614 | break; | |
615 | case ide_dma_read: | |
616 | reading = 1; | |
617 | @@ -1612,7 +1644,14 @@ | |
618 | ||
619 | /* Note: We support only master drives for now. This will have to be | |
620 | * improved if we want to handle sleep on the iMacDV where the CD-ROM | |
621 | - * is a slave | |
622 | + * is a slave. | |
623 | + * | |
624 | + * Well, actually, that sorta works on the iBook2 when the CD-ROM is | |
625 | + * a slave, though it will fail to spin_wait_hwgroup for the slave | |
626 | + * device as it is marked busy by the master sleep code. Well, it's | |
627 | + * probably not worth fixing now as we don't have sleep code for | |
628 | + * ATAPI devices anyway. Future kernels will hopefully deal with | |
629 | + * IDE PM in a more generic way. | |
630 | */ | |
631 | static int __pmac | |
632 | idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when) | |
633 | diff -Nur linux-2.4.19/drivers/ide/ide-probe.c linux-2.4.19.new/drivers/ide/ide-probe.c | |
634 | --- linux-2.4.19/drivers/ide/ide-probe.c Sat Aug 3 02:39:44 2002 | |
635 | +++ linux-2.4.19.new/drivers/ide/ide-probe.c Wed Nov 13 09:49:39 2002 | |
636 | @@ -785,6 +785,7 @@ | |
637 | gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL); | |
638 | if (!gd) | |
639 | goto err_kmalloc_gd; | |
640 | + memset (gd, 0, sizeof(struct gendisk)); | |
641 | gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL); | |
642 | if (!gd->sizes) | |
643 | goto err_kmalloc_gd_sizes; | |
644 | diff -Nur linux-2.4.19/drivers/ide/ide-sibyte.c linux-2.4.19.new/drivers/ide/ide-sibyte.c | |
645 | --- linux-2.4.19/drivers/ide/ide-sibyte.c Thu Jan 1 01:00:00 1970 | |
646 | +++ linux-2.4.19.new/drivers/ide/ide-sibyte.c Wed Nov 13 09:49:39 2002 | |
647 | @@ -0,0 +1,333 @@ | |
648 | +/* | |
649 | + * Copyright (C) 2001 Broadcom Corporation | |
650 | + * | |
651 | + * This program is free software; you can redistribute it and/or | |
652 | + * modify it under the terms of the GNU General Public License | |
653 | + * as published by the Free Software Foundation; either version 2 | |
654 | + * of the License, or (at your option) any later version. | |
655 | + * | |
656 | + * This program is distributed in the hope that it will be useful, | |
657 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
658 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
659 | + * GNU General Public License for more details. | |
660 | + * | |
661 | + * You should have received a copy of the GNU General Public License | |
662 | + * along with this program; if not, write to the Free Software | |
663 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
664 | + */ | |
665 | + | |
666 | +/* Derived loosely from ide-pmac.c, so: | |
667 | + * | |
668 | + * Copyright (C) 1998 Paul Mackerras. | |
669 | + * Copyright (C) 1995-1998 Mark Lord | |
670 | + */ | |
671 | +#include <linux/config.h> | |
672 | +#include <linux/types.h> | |
673 | +#include <linux/kernel.h> | |
674 | +#include <linux/sched.h> | |
675 | +#include <linux/init.h> | |
676 | +#include <linux/delay.h> | |
677 | +#include <linux/ide.h> | |
678 | + | |
679 | +#include <asm/irq.h> | |
680 | +#include <asm/io.h> | |
681 | +#include <asm/sibyte/sb1250_regs.h> | |
682 | +#include <asm/sibyte/sb1250_int.h> | |
683 | +#include <asm/sibyte/sb1250_genbus.h> | |
684 | +#include <asm/sibyte/64bit.h> | |
685 | +#include <asm/sibyte/board.h> | |
686 | + | |
687 | +/* Note: this should be general for any board using IDE on GenBus */ | |
688 | + | |
689 | +extern struct ide_ops std_ide_ops; | |
690 | + | |
691 | +static ide_hwif_t *sb_ide_hwif = NULL; | |
692 | +static unsigned long ide_base; | |
693 | + | |
694 | +#define SIBYTE_IDE_BASE (KSEG1ADDR(ide_base)-mips_io_port_base) | |
695 | +#define SIBYTE_IDE_REG(pcaddr) (SIBYTE_IDE_BASE + ((pcaddr)<<5)) | |
696 | + | |
697 | +/* | |
698 | + * We are limiting the number of PCI-IDE devices to leave room for | |
699 | + * GenBus IDE (and possibly PCMCIA/CF?) | |
700 | + */ | |
701 | +static int sibyte_ide_default_irq(ide_ioreg_t base) | |
702 | +{ | |
703 | + return 0; | |
704 | +} | |
705 | + | |
706 | +static ide_ioreg_t sibyte_ide_default_io_base(int index) | |
707 | +{ | |
708 | + return 0; | |
709 | +} | |
710 | + | |
711 | +static void sibyte_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, | |
712 | + ide_ioreg_t ctrl_port, int *irq) | |
713 | +{ | |
714 | + std_ide_ops.ide_init_hwif_ports(hw, data_port, ctrl_port, irq); | |
715 | +} | |
716 | + | |
717 | +static int sibyte_ide_request_irq(unsigned int irq, | |
718 | + void (*handler)(int,void *, struct pt_regs *), | |
719 | + unsigned long flags, const char *device, | |
720 | + void *dev_id) | |
721 | +{ | |
722 | + return request_irq(irq, handler, flags, device, dev_id); | |
723 | +} | |
724 | + | |
725 | +static void sibyte_ide_free_irq(unsigned int irq, void *dev_id) | |
726 | +{ | |
727 | + free_irq(irq, dev_id); | |
728 | +} | |
729 | + | |
730 | +static inline int is_sibyte_ide(ide_ioreg_t from) | |
731 | +{ | |
732 | + return (sb_ide_hwif && | |
733 | + ((from == sb_ide_hwif->io_ports[IDE_DATA_OFFSET]) || | |
734 | + (from == sb_ide_hwif->io_ports[IDE_ERROR_OFFSET]) || | |
735 | + (from == sb_ide_hwif->io_ports[IDE_NSECTOR_OFFSET]) || | |
736 | + (from == sb_ide_hwif->io_ports[IDE_SECTOR_OFFSET]) || | |
737 | + (from == sb_ide_hwif->io_ports[IDE_LCYL_OFFSET]) || | |
738 | + (from == sb_ide_hwif->io_ports[IDE_HCYL_OFFSET]) || | |
739 | + (from == sb_ide_hwif->io_ports[IDE_SELECT_OFFSET]) || | |
740 | + (from == sb_ide_hwif->io_ports[IDE_STATUS_OFFSET]) || | |
741 | + (from == sb_ide_hwif->io_ports[IDE_CONTROL_OFFSET]))); | |
742 | +} | |
743 | + | |
744 | +static int sibyte_ide_check_region(ide_ioreg_t from, unsigned int extent) | |
745 | +{ | |
746 | + /* Figure out if it's the SiByte IDE; if so, don't do anything | |
747 | + since our I/O space is in a weird place. */ | |
748 | + if (is_sibyte_ide(from)) | |
749 | + return 0; | |
750 | + else | |
751 | +#ifdef CONFIG_BLK_DEV_IDE | |
752 | + return std_ide_ops.ide_check_region(from, extent); | |
753 | +#else | |
754 | + return 0; | |
755 | +#endif | |
756 | +} | |
757 | + | |
758 | +static void sibyte_ide_request_region(ide_ioreg_t from, unsigned int extent, | |
759 | + const char *name) | |
760 | +{ | |
761 | +#ifdef CONFIG_BLK_DEV_IDE | |
762 | + if (!is_sibyte_ide(from)) | |
763 | + std_ide_ops.ide_request_region(from, extent, name); | |
764 | +#endif | |
765 | +} | |
766 | + | |
767 | +static void sibyte_ide_release_region(ide_ioreg_t from, unsigned int extent) | |
768 | +{ | |
769 | +#ifdef CONFIG_BLK_DEV_IDE | |
770 | + if (!is_sibyte_ide(from)) | |
771 | + std_ide_ops.ide_release_region(from, extent); | |
772 | +#endif | |
773 | +} | |
774 | + | |
775 | +struct ide_ops sibyte_ide_ops = { | |
776 | + &sibyte_ide_default_irq, | |
777 | + &sibyte_ide_default_io_base, | |
778 | + &sibyte_ide_init_hwif_ports, | |
779 | + &sibyte_ide_request_irq, | |
780 | + &sibyte_ide_free_irq, | |
781 | + &sibyte_ide_check_region, | |
782 | + &sibyte_ide_request_region, | |
783 | + &sibyte_ide_release_region | |
784 | +}; | |
785 | + | |
786 | +/* | |
787 | + * I/O operations. The FPGA for SiByte generic bus IDE deals with | |
788 | + * byte-swapping for us, so we can't share the I/O macros with other | |
789 | + * IDE (e.g. PCI-IDE) devices. | |
790 | + */ | |
791 | + | |
792 | +#define sibyte_outb(val,port) \ | |
793 | +do { \ | |
794 | + *(volatile u8 *)(mips_io_port_base + (port)) = val; \ | |
795 | +} while(0) | |
796 | + | |
797 | +#define sibyte_outw(val,port) \ | |
798 | +do { \ | |
799 | + *(volatile u16 *)(mips_io_port_base + (port)) = val; \ | |
800 | +} while(0) | |
801 | + | |
802 | +#define sibyte_outl(val,port) \ | |
803 | +do { \ | |
804 | + *(volatile u32 *)(mips_io_port_base + (port)) = val; \ | |
805 | +} while(0) | |
806 | + | |
807 | +static inline unsigned char sibyte_inb(unsigned long port) | |
808 | +{ | |
809 | + return (*(volatile u8 *)(mips_io_port_base + (port))); | |
810 | +} | |
811 | + | |
812 | +static inline unsigned short sibyte_inw(unsigned long port) | |
813 | +{ | |
814 | + return (*(volatile u16 *)(mips_io_port_base + (port))); | |
815 | +} | |
816 | + | |
817 | +static inline unsigned int sibyte_inl(unsigned long port) | |
818 | +{ | |
819 | + return (*(volatile u32 *)(mips_io_port_base + (port))); | |
820 | +} | |
821 | + | |
822 | + | |
823 | +static inline void sibyte_outsb(unsigned long port, void *addr, unsigned int count) | |
824 | +{ | |
825 | + while (count--) { | |
826 | + sibyte_outb(*(u8 *)addr, port); | |
827 | + addr++; | |
828 | + } | |
829 | +} | |
830 | + | |
831 | +static inline void sibyte_insb(unsigned long port, void *addr, unsigned int count) | |
832 | +{ | |
833 | + while (count--) { | |
834 | + *(u8 *)addr = sibyte_inb(port); | |
835 | + addr++; | |
836 | + } | |
837 | +} | |
838 | + | |
839 | +static inline void sibyte_outsw(unsigned long port, void *addr, unsigned int count) | |
840 | +{ | |
841 | + while (count--) { | |
842 | + sibyte_outw(*(u16 *)addr, port); | |
843 | + addr += 2; | |
844 | + } | |
845 | +} | |
846 | + | |
847 | +static inline void sibyte_insw(unsigned long port, void *addr, unsigned int count) | |
848 | +{ | |
849 | + while (count--) { | |
850 | + *(u16 *)addr = sibyte_inw(port); | |
851 | + addr += 2; | |
852 | + } | |
853 | +} | |
854 | + | |
855 | +static inline void sibyte_outsl(unsigned long port, void *addr, unsigned int count) | |
856 | +{ | |
857 | + while (count--) { | |
858 | + sibyte_outl(*(u32 *)addr, port); | |
859 | + addr += 4; | |
860 | + } | |
861 | +} | |
862 | + | |
863 | +static inline void sibyte_insl(unsigned long port, void *addr, unsigned int count) | |
864 | +{ | |
865 | + while (count--) { | |
866 | + *(u32 *)addr = sibyte_inl(port); | |
867 | + addr += 4; | |
868 | + } | |
869 | +} | |
870 | + | |
871 | +static void sibyte_ideproc(ide_ide_action_t action, ide_drive_t *drive, | |
872 | + void *buffer, unsigned int count) | |
873 | +{ | |
874 | + /* slow? vlb_sync? */ | |
875 | + switch (action) { | |
876 | + case ideproc_ide_input_data: | |
877 | + if (drive->io_32bit) { | |
878 | + sibyte_insl(IDE_DATA_REG, buffer, count); | |
879 | + } else { | |
880 | + sibyte_insw(IDE_DATA_REG, buffer, count<<1); | |
881 | + } | |
882 | + break; | |
883 | + case ideproc_ide_output_data: | |
884 | + if (drive->io_32bit) { | |
885 | + sibyte_outsl(IDE_DATA_REG, buffer, count); | |
886 | + } else { | |
887 | + sibyte_outsw(IDE_DATA_REG, buffer, count<<1); | |
888 | + } | |
889 | + break; | |
890 | + case ideproc_atapi_input_bytes: | |
891 | + count++; | |
892 | + if (drive->io_32bit) { | |
893 | + sibyte_insl(IDE_DATA_REG, buffer, count>>2); | |
894 | + } else { | |
895 | + sibyte_insw(IDE_DATA_REG, buffer, count>>1); | |
896 | + } | |
897 | + if ((count & 3) >= 2) | |
898 | + sibyte_insw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1); | |
899 | + break; | |
900 | + case ideproc_atapi_output_bytes: | |
901 | + count++; | |
902 | + if (drive->io_32bit) { | |
903 | + sibyte_outsl(IDE_DATA_REG, buffer, count>>2); | |
904 | + } else { | |
905 | + sibyte_outsw(IDE_DATA_REG, buffer, count>>1); | |
906 | + } | |
907 | + if ((count & 3) >= 2) | |
908 | + sibyte_outsw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1); | |
909 | + break; | |
910 | + } | |
911 | +} | |
912 | + | |
913 | +/* | |
914 | + * selectproc and intrproc aren't really necessary, since | |
915 | + * byte-swapping doesn't affect byte ops; they are included for | |
916 | + * consistency. | |
917 | + */ | |
918 | +static void sibyte_selectproc(ide_drive_t *drive) | |
919 | +{ | |
920 | + sibyte_outb(drive->select.all, IDE_SELECT_REG); | |
921 | +} | |
922 | + | |
923 | +static void sibyte_intrproc(ide_drive_t *drive) | |
924 | +{ | |
925 | + sibyte_outb(drive->ctl|2, IDE_CONTROL_REG); | |
926 | +} | |
927 | + | |
928 | +void __init sibyte_ide_probe(void) | |
929 | +{ | |
930 | + int i; | |
931 | + ide_hwif_t *hwif; | |
932 | + /* | |
933 | + * Find the first untaken slot in hwifs | |
934 | + */ | |
935 | + for (i = 0; i < MAX_HWIFS; i++) { | |
936 | + if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) { | |
937 | + break; | |
938 | + } | |
939 | + } | |
940 | + if (i == MAX_HWIFS) { | |
941 | + printk("No space for SiByte onboard IDE driver in ide_hwifs[]. Not enabled.\n"); | |
942 | + return; | |
943 | + } | |
944 | + | |
945 | + /* Find memory base address */ | |
946 | +#ifdef __MIPSEL__ | |
947 | + /* Pass1 workaround (bug 1624) */ | |
948 | + if (sb1250_pass == K_SYS_REVISION_PASS1) | |
949 | + ide_base = G_IO_START_ADDR(csr_in32(4+(IO_SPACE_BASE|A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS))))) << S_IO_ADDRBASE; | |
950 | + else | |
951 | +#endif | |
952 | + ide_base = G_IO_START_ADDR(csr_in32(IO_SPACE_BASE|A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)))) << S_IO_ADDRBASE; | |
953 | + | |
954 | + /* | |
955 | + * Set up our stuff; we're a little odd because our io_ports | |
956 | + * aren't in the usual place, and byte-swapping isn't | |
957 | + * necessary. | |
958 | + */ | |
959 | + hwif = &ide_hwifs[i]; | |
960 | + hwif->hw.io_ports[IDE_DATA_OFFSET] = SIBYTE_IDE_REG(0x1f0); | |
961 | + hwif->hw.io_ports[IDE_ERROR_OFFSET] = SIBYTE_IDE_REG(0x1f1); | |
962 | + hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f2); | |
963 | + hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f3); | |
964 | + hwif->hw.io_ports[IDE_LCYL_OFFSET] = SIBYTE_IDE_REG(0x1f4); | |
965 | + hwif->hw.io_ports[IDE_HCYL_OFFSET] = SIBYTE_IDE_REG(0x1f5); | |
966 | + hwif->hw.io_ports[IDE_SELECT_OFFSET] = SIBYTE_IDE_REG(0x1f6); | |
967 | + hwif->hw.io_ports[IDE_STATUS_OFFSET] = SIBYTE_IDE_REG(0x1f7); | |
968 | + hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SIBYTE_IDE_REG(0x3f6); | |
969 | + hwif->hw.irq = K_INT_GB_IDE; | |
970 | + hwif->irq = K_INT_GB_IDE; | |
971 | + hwif->noprobe = 0; | |
972 | + /* Use our own non-byte-swapping routines */ | |
973 | + hwif->ideproc = sibyte_ideproc; | |
974 | + hwif->selectproc = sibyte_selectproc; | |
975 | + hwif->intrproc = sibyte_intrproc; | |
976 | + | |
977 | + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | |
978 | + printk("SiByte onboard IDE configured as device %i\n", i); | |
979 | + sb_ide_hwif = hwif; | |
980 | +} | |
981 | diff -Nur linux-2.4.19/drivers/ide/ide-swarm.c linux-2.4.19.new/drivers/ide/ide-swarm.c | |
982 | --- linux-2.4.19/drivers/ide/ide-swarm.c Sat Aug 3 02:39:44 2002 | |
983 | +++ linux-2.4.19.new/drivers/ide/ide-swarm.c Thu Jan 1 01:00:00 1970 | |
984 | @@ -1,73 +0,0 @@ | |
985 | -/* | |
986 | - * Copyright (C) 2001 Broadcom Corporation | |
987 | - * | |
988 | - * This program is free software; you can redistribute it and/or | |
989 | - * modify it under the terms of the GNU General Public License | |
990 | - * as published by the Free Software Foundation; either version 2 | |
991 | - * of the License, or (at your option) any later version. | |
992 | - * | |
993 | - * This program is distributed in the hope that it will be useful, | |
994 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
995 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
996 | - * GNU General Public License for more details. | |
997 | - * | |
998 | - * You should have received a copy of the GNU General Public License | |
999 | - * along with this program; if not, write to the Free Software | |
1000 | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
1001 | - */ | |
1002 | - | |
1003 | -/* Derived loosely from ide-pmac.c, so: | |
1004 | - * | |
1005 | - * Copyright (C) 1998 Paul Mackerras. | |
1006 | - * Copyright (C) 1995-1998 Mark Lord | |
1007 | - */ | |
1008 | -#include <linux/config.h> | |
1009 | -#include <linux/types.h> | |
1010 | -#include <linux/kernel.h> | |
1011 | -#include <linux/sched.h> | |
1012 | -#include <linux/init.h> | |
1013 | -#include <linux/delay.h> | |
1014 | -#include <linux/ide.h> | |
1015 | -#include <asm/irq.h> | |
1016 | -#include <asm/io.h> | |
1017 | -#include <asm/sibyte/sb1250_int.h> | |
1018 | -#include <asm/sibyte/swarm_ide.h> | |
1019 | - | |
1020 | -void __init swarm_ide_probe(void) | |
1021 | -{ | |
1022 | - int i; | |
1023 | - ide_hwif_t *hwif; | |
1024 | - /* | |
1025 | - * Find the first untaken slot in hwifs | |
1026 | - */ | |
1027 | - for (i = 0; i < MAX_HWIFS; i++) { | |
1028 | - if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) { | |
1029 | - break; | |
1030 | - } | |
1031 | - } | |
1032 | - if (i == MAX_HWIFS) { | |
1033 | - printk("No space for SWARM onboard IDE driver in ide_hwifs[]. Not enabled.\n"); | |
1034 | - return; | |
1035 | - } | |
1036 | - | |
1037 | - /* Set up our stuff */ | |
1038 | - hwif = &ide_hwifs[i]; | |
1039 | - hwif->hw.io_ports[IDE_DATA_OFFSET] = SWARM_IDE_REG(0x1f0); | |
1040 | - hwif->hw.io_ports[IDE_ERROR_OFFSET] = SWARM_IDE_REG(0x1f1); | |
1041 | - hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SWARM_IDE_REG(0x1f2); | |
1042 | - hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SWARM_IDE_REG(0x1f3); | |
1043 | - hwif->hw.io_ports[IDE_LCYL_OFFSET] = SWARM_IDE_REG(0x1f4); | |
1044 | - hwif->hw.io_ports[IDE_HCYL_OFFSET] = SWARM_IDE_REG(0x1f5); | |
1045 | - hwif->hw.io_ports[IDE_SELECT_OFFSET] = SWARM_IDE_REG(0x1f6); | |
1046 | - hwif->hw.io_ports[IDE_STATUS_OFFSET] = SWARM_IDE_REG(0x1f7); | |
1047 | - hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SWARM_IDE_REG(0x3f6); | |
1048 | - hwif->hw.io_ports[IDE_IRQ_OFFSET] = SWARM_IDE_REG(0x3f7); | |
1049 | -// hwif->hw->ack_intr = swarm_ide_ack_intr; | |
1050 | - hwif->hw.irq = SWARM_IDE_INT; | |
1051 | - hwif->ideproc = swarm_ideproc; | |
1052 | - | |
1053 | - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | |
1054 | - hwif->irq = hwif->hw.irq; | |
1055 | - printk("SWARM onboard IDE configured as device %i\n", i); | |
1056 | -} | |
1057 | - | |
1058 | diff -Nur linux-2.4.19/drivers/ide/ide.c linux-2.4.19.new/drivers/ide/ide.c | |
1059 | --- linux-2.4.19/drivers/ide/ide.c Sat Aug 3 02:39:44 2002 | |
1060 | +++ linux-2.4.19.new/drivers/ide/ide.c Wed Nov 13 09:49:39 2002 | |
1061 | @@ -3418,7 +3418,7 @@ | |
1062 | const char *ide_words[] = { | |
1063 | "noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", | |
1064 | "minus8", "minus9", "minus10", | |
1065 | - "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL }; | |
1066 | + "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", "nohighio", NULL }; | |
1067 | hw = s[3] - '0'; | |
1068 | hwif = &ide_hwifs[hw]; | |
1069 | i = match_parm(&s[4], ide_words, vals, 3); | |
1070 | @@ -3437,6 +3437,10 @@ | |
1071 | } | |
1072 | ||
1073 | switch (i) { | |
1074 | + case -19: /* nohighio */ | |
1075 | + hwif->no_highio = 1; | |
1076 | + printk("%s: disabled high i/o capability\n", hwif->name); | |
1077 | + goto done; | |
1078 | #ifdef CONFIG_BLK_DEV_PDC4030 | |
1079 | case -18: /* "dc4030" */ | |
1080 | { | |
1081 | @@ -3616,12 +3620,12 @@ | |
1082 | pmac_ide_probe(); | |
1083 | } | |
1084 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | |
1085 | -#ifdef CONFIG_BLK_DEV_IDE_SWARM | |
1086 | +#ifdef CONFIG_BLK_DEV_IDE_SIBYTE | |
1087 | { | |
1088 | - extern void swarm_ide_probe(void); | |
1089 | - swarm_ide_probe(); | |
1090 | + extern void sibyte_ide_probe(void); | |
1091 | + sibyte_ide_probe(); | |
1092 | } | |
1093 | -#endif /* CONFIG_BLK_DEV_IDE_SWARM */ | |
1094 | +#endif /* CONFIG_BLK_DEV_IDE_SIBYTE */ | |
1095 | #ifdef CONFIG_BLK_DEV_IDE_ICSIDE | |
1096 | { | |
1097 | extern void icside_init(void); | |
1098 | diff -Nur linux-2.4.19/drivers/ide/q40ide.c linux-2.4.19.new/drivers/ide/q40ide.c | |
1099 | --- linux-2.4.19/drivers/ide/q40ide.c Thu Oct 25 22:53:47 2001 | |
1100 | +++ linux-2.4.19.new/drivers/ide/q40ide.c Wed Nov 13 09:49:39 2002 | |
1101 | @@ -82,8 +82,8 @@ | |
1102 | for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { | |
1103 | hw_regs_t hw; | |
1104 | ||
1105 | - ide_setup_ports(&hw,(ide_ioreg_t) pcide_bases[i], (int *)pcide_offsets, | |
1106 | - pcide_bases[i]+0x206, | |
1107 | + ide_setup_ports(&hw, (ide_ioreg_t)pcide_bases[i], (int *)pcide_offsets, | |
1108 | + (ide_ioreg_t)pcide_bases[i]+0x206, | |
1109 | 0, NULL, q40ide_default_irq(pcide_bases[i])); | |
1110 | ide_register_hw(&hw, NULL); | |
1111 | } | |
1112 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/linux/ide.h linux-2.4.20/include/linux/ide.h | |
1113 | --- linux-2.4.19/include/linux/ide.h 2002-08-03 00:39:45.000000000 +0000 | |
1114 | +++ linux-2.4.20/include/linux/ide.h 2002-10-29 11:18:34.000000000 +0000 | |
1115 | @@ -552,6 +552,7 @@ | |
1116 | unsigned reset : 1; /* reset after probe */ | |
1117 | unsigned autodma : 1; /* automatically try to enable DMA at boot */ | |
1118 | unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ | |
1119 | + unsigned no_highio : 1; /* don't trust pci dma mask, bounce */ | |
1120 | byte channel; /* for dual-port chips: 0=primary, 1=secondary */ | |
1121 | #ifdef CONFIG_BLK_DEV_IDEPCI | |
1122 | struct pci_dev *pci_dev; /* for pci chipsets */ | |
1123 | @@ -874,6 +875,21 @@ | |
1124 | } ide_action_t; | |
1125 | ||
1126 | /* | |
1127 | + * temporarily mapping a (possible) highmem bio | |
1128 | + */ | |
1129 | +#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) | |
1130 | + | |
1131 | +extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags) | |
1132 | +{ | |
1133 | + return bh_kmap_irq(rq->bh, flags) + ide_rq_offset(rq); | |
1134 | +} | |
1135 | + | |
1136 | +extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) | |
1137 | +{ | |
1138 | + bh_kunmap_irq(buffer, flags); | |
1139 | +} | |
1140 | + | |
1141 | +/* | |
1142 | * This function issues a special IDE device request | |
1143 | * onto the request queue. | |
1144 | * | |
1145 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/linux/blkdev.h linux-2.4.20/include/linux/blkdev.h | |
1146 | --- linux-2.4.19/include/linux/blkdev.h 2002-08-03 00:39:45.000000000 +0000 | |
1147 | +++ linux-2.4.20/include/linux/blkdev.h 2002-10-29 11:18:34.000000000 +0000 | |
1148 | @@ -6,6 +6,9 @@ | |
1149 | #include <linux/genhd.h> | |
1150 | #include <linux/tqueue.h> | |
1151 | #include <linux/list.h> | |
1152 | +#include <linux/mm.h> | |
1153 | + | |
1154 | +#include <asm/io.h> | |
1155 | ||
1156 | struct request_queue; | |
1157 | typedef struct request_queue request_queue_t; | |
1158 | @@ -36,7 +39,7 @@ | |
1159 | unsigned long hard_sector, hard_nr_sectors; | |
1160 | unsigned int nr_segments; | |
1161 | unsigned int nr_hw_segments; | |
1162 | - unsigned long current_nr_sectors; | |
1163 | + unsigned long current_nr_sectors, hard_cur_sectors; | |
1164 | void * special; | |
1165 | char * buffer; | |
1166 | struct completion * waiting; | |
1167 | @@ -123,6 +126,8 @@ | |
1168 | */ | |
1169 | char head_active; | |
1170 | ||
1171 | + unsigned long bounce_pfn; | |
1172 | + | |
1173 | /* | |
1174 | * Is meant to protect the queue in the future instead of | |
1175 | * io_request_lock | |
1176 | @@ -135,6 +140,38 @@ | |
1177 | wait_queue_head_t wait_for_requests[2]; | |
1178 | }; | |
1179 | ||
1180 | +extern unsigned long blk_max_low_pfn, blk_max_pfn; | |
1181 | + | |
1182 | +#define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT) | |
1183 | +#define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT) | |
1184 | + | |
1185 | +extern void blk_queue_bounce_limit(request_queue_t *, u64); | |
1186 | + | |
1187 | +#ifdef CONFIG_HIGHMEM | |
1188 | +extern struct buffer_head *create_bounce(int, struct buffer_head *); | |
1189 | +extern inline struct buffer_head *blk_queue_bounce(request_queue_t *q, int rw, | |
1190 | + struct buffer_head *bh) | |
1191 | +{ | |
1192 | + struct page *page = bh->b_page; | |
1193 | + | |
1194 | +#ifndef CONFIG_DISCONTIGMEM | |
1195 | + if (page - mem_map <= q->bounce_pfn) | |
1196 | +#else | |
1197 | + if ((page - page_zone(page)->zone_mem_map) + (page_zone(page)->zone_start_paddr >> PAGE_SHIFT) <= q->bounce_pfn) | |
1198 | +#endif | |
1199 | + return bh; | |
1200 | + | |
1201 | + return create_bounce(rw, bh); | |
1202 | +} | |
1203 | +#else | |
1204 | +#define blk_queue_bounce(q, rw, bh) (bh) | |
1205 | +#endif | |
1206 | + | |
1207 | +#define bh_phys(bh) (page_to_phys((bh)->b_page) + bh_offset((bh))) | |
1208 | + | |
1209 | +#define BH_CONTIG(b1, b2) (bh_phys((b1)) + (b1)->b_size == bh_phys((b2))) | |
1210 | +#define BH_PHYS_4G(b1, b2) ((bh_phys((b1)) | 0xffffffff) == ((bh_phys((b2)) + (b2)->b_size - 1) | 0xffffffff)) | |
1211 | + | |
1212 | struct blk_dev_struct { | |
1213 | /* | |
1214 | * queue_proc has to be atomic | |
1215 | @@ -174,6 +211,7 @@ | |
1216 | extern void blk_queue_headactive(request_queue_t *, int); | |
1217 | extern void blk_queue_make_request(request_queue_t *, make_request_fn *); | |
1218 | extern void generic_unplug_device(void *); | |
1219 | +extern inline int blk_seg_merge_ok(struct buffer_head *, struct buffer_head *); | |
1220 | ||
1221 | extern int * blk_size[MAX_BLKDEV]; | |
1222 | ||
1223 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/linux/highmem.h linux-2.4.20/include/linux/highmem.h | |
1224 | --- linux-2.4.19/include/linux/highmem.h 2002-08-03 00:39:45.000000000 +0000 | |
1225 | +++ linux-2.4.20/include/linux/highmem.h 2002-10-29 11:18:34.000000000 +0000 | |
1226 | @@ -13,8 +13,7 @@ | |
1227 | /* declarations for linux/mm/highmem.c */ | |
1228 | unsigned int nr_free_highpages(void); | |
1229 | ||
1230 | -extern struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig); | |
1231 | - | |
1232 | +extern struct buffer_head *create_bounce(int rw, struct buffer_head * bh_orig); | |
1233 | ||
1234 | static inline char *bh_kmap(struct buffer_head *bh) | |
1235 | { | |
1236 | @@ -26,6 +25,42 @@ | |
1237 | kunmap(bh->b_page); | |
1238 | } | |
1239 | ||
1240 | +/* | |
1241 | + * remember to add offset! and never ever reenable interrupts between a | |
1242 | + * bh_kmap_irq and bh_kunmap_irq!! | |
1243 | + */ | |
1244 | +static inline char *bh_kmap_irq(struct buffer_head *bh, unsigned long *flags) | |
1245 | +{ | |
1246 | + unsigned long addr; | |
1247 | + | |
1248 | + __save_flags(*flags); | |
1249 | + | |
1250 | + /* | |
1251 | + * could be low | |
1252 | + */ | |
1253 | + if (!PageHighMem(bh->b_page)) | |
1254 | + return bh->b_data; | |
1255 | + | |
1256 | + /* | |
1257 | + * it's a highmem page | |
1258 | + */ | |
1259 | + __cli(); | |
1260 | + addr = (unsigned long) kmap_atomic(bh->b_page, KM_BH_IRQ); | |
1261 | + | |
1262 | + if (addr & ~PAGE_MASK) | |
1263 | + BUG(); | |
1264 | + | |
1265 | + return (char *) addr + bh_offset(bh); | |
1266 | +} | |
1267 | + | |
1268 | +static inline void bh_kunmap_irq(char *buffer, unsigned long *flags) | |
1269 | +{ | |
1270 | + unsigned long ptr = (unsigned long) buffer & PAGE_MASK; | |
1271 | + | |
1272 | + kunmap_atomic((void *) ptr, KM_BH_IRQ); | |
1273 | + __restore_flags(*flags); | |
1274 | +} | |
1275 | + | |
1276 | #else /* CONFIG_HIGHMEM */ | |
1277 | ||
1278 | static inline unsigned int nr_free_highpages(void) { return 0; } | |
1279 | @@ -37,8 +72,10 @@ | |
1280 | #define kmap_atomic(page,idx) kmap(page) | |
1281 | #define kunmap_atomic(page,idx) kunmap(page) | |
1282 | ||
1283 | -#define bh_kmap(bh) ((bh)->b_data) | |
1284 | -#define bh_kunmap(bh) do { } while (0) | |
1285 | +#define bh_kmap(bh) ((bh)->b_data) | |
1286 | +#define bh_kunmap(bh) do { } while (0) | |
1287 | +#define bh_kmap_irq(bh, flags) ((bh)->b_data) | |
1288 | +#define bh_kunmap_irq(bh, flags) do { *(flags) = 0; } while (0) | |
1289 | ||
1290 | #endif /* CONFIG_HIGHMEM */ | |
1291 | ||
74783475 | 1292 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/asm-i386/kmap_types.h linux-2.4.20/include/asm-i386/kmap_types.h |
1293 | --- linux-2.4.19/include/asm-i386/kmap_types.h 2001-09-17 20:16:30.000000000 +0000 | |
1294 | +++ linux-2.4.20/include/asm-i386/kmap_types.h 2002-10-29 11:18:49.000000000 +0000 | |
1295 | @@ -3,10 +3,11 @@ | |
1296 | ||
1297 | enum km_type { | |
1298 | KM_BOUNCE_READ, | |
1299 | - KM_SKB_DATA, | |
1300 | + KM_SKB_SUNRPC_DATA, | |
1301 | KM_SKB_DATA_SOFTIRQ, | |
1302 | KM_USER0, | |
1303 | KM_USER1, | |
1304 | + KM_BH_IRQ, | |
1305 | KM_BIO_IRQ, | |
1306 | KM_TYPE_NR | |
1307 | }; | |
1308 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/asm-ppc/kmap_types.h linux-2.4.20/include/asm-ppc/kmap_types.h | |
1309 | --- linux-2.4.19/include/asm-ppc/kmap_types.h 2001-09-17 20:16:30.000000000 +0000 | |
1310 | +++ linux-2.4.20/include/asm-ppc/kmap_types.h 2002-10-29 11:18:34.000000000 +0000 | |
1311 | @@ -7,10 +7,11 @@ | |
1312 | ||
1313 | enum km_type { | |
1314 | KM_BOUNCE_READ, | |
1315 | - KM_SKB_DATA, | |
1316 | + KM_SKB_SUNRPC_DATA, | |
1317 | KM_SKB_DATA_SOFTIRQ, | |
1318 | KM_USER0, | |
1319 | KM_USER1, | |
1320 | + KM_BH_IRQ, | |
1321 | KM_BIO_IRQ, | |
1322 | KM_TYPE_NR | |
1323 | }; | |
1324 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/asm-sparc/kmap_types.h linux-2.4.20/include/asm-sparc/kmap_types.h | |
1325 | --- linux-2.4.19/include/asm-sparc/kmap_types.h 2001-09-17 20:16:30.000000000 +0000 | |
1326 | +++ linux-2.4.20/include/asm-sparc/kmap_types.h 2002-10-29 11:18:34.000000000 +0000 | |
1327 | @@ -3,10 +3,11 @@ | |
1328 | ||
1329 | enum km_type { | |
1330 | KM_BOUNCE_READ, | |
1331 | - KM_SKB_DATA, | |
1332 | + KM_SKB_SUNRPC_DATA, | |
1333 | KM_SKB_DATA_SOFTIRQ, | |
1334 | KM_USER0, | |
1335 | KM_USER1, | |
1336 | + KM_BH_IRQ, | |
1337 | KM_BIO_IRQ, | |
1338 | KM_TYPE_NR | |
1339 | }; | |
1340 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/asm-x86_64/kmap_types.h linux-2.4.20/include/asm-x86_64/kmap_types.h | |
1341 | --- linux-2.4.19/include/asm-x86_64/kmap_types.h 1970-01-01 00:00:00.000000000 +0000 | |
1342 | +++ linux-2.4.20/include/asm-x86_64/kmap_types.h 2002-10-29 11:18:39.000000000 +0000 | |
1343 | @@ -0,0 +1,14 @@ | |
1344 | +#ifndef _ASM_KMAP_TYPES_H | |
1345 | +#define _ASM_KMAP_TYPES_H | |
1346 | + | |
1347 | +enum km_type { | |
1348 | + KM_BOUNCE_READ, | |
1349 | + KM_SKB_SUNRPC_DATA, | |
1350 | + KM_SKB_DATA_SOFTIRQ, | |
1351 | + KM_USER0, | |
1352 | + KM_USER1, | |
1353 | + KM_BH_IRQ, | |
1354 | + KM_TYPE_NR | |
1355 | +}; | |
1356 | + | |
1357 | +#endif | |
b01caadc | 1358 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/drivers/block/ll_rw_blk.c linux-2.4.20/drivers/block/ll_rw_blk.c |
1359 | --- linux-2.4.19/drivers/block/ll_rw_blk.c 2002-08-03 00:39:43.000000000 +0000 | |
1360 | +++ linux-2.4.20/drivers/block/ll_rw_blk.c 2002-10-29 11:18:33.000000000 +0000 | |
1361 | @@ -23,6 +23,7 @@ | |
1362 | #include <linux/init.h> | |
1363 | #include <linux/smp_lock.h> | |
1364 | #include <linux/completion.h> | |
1365 | +#include <linux/bootmem.h> | |
1366 | ||
1367 | #include <asm/system.h> | |
1368 | #include <asm/io.h> | |
1369 | @@ -117,6 +118,9 @@ | |
1370 | */ | |
1371 | int * max_sectors[MAX_BLKDEV]; | |
1372 | ||
1373 | +unsigned long blk_max_low_pfn, blk_max_pfn; | |
1374 | +int blk_nohighio = 0; | |
1375 | + | |
1376 | static inline int get_max_sectors(kdev_t dev) | |
1377 | { | |
1378 | if (!max_sectors[MAJOR(dev)]) | |
1379 | @@ -238,6 +242,55 @@ | |
1380 | q->make_request_fn = mfn; | |
1381 | } | |
1382 | ||
1383 | +/** | |
1384 | + * blk_queue_bounce_limit - set bounce buffer limit for queue | |
1385 | + * @q: the request queue for the device | |
1386 | + * @dma_addr: bus address limit | |
1387 | + * | |
1388 | + * Description: | |
1389 | + * Different hardware can have different requirements as to what pages | |
1390 | + * it can do I/O directly to. A low level driver can call | |
1391 | + * blk_queue_bounce_limit to have lower memory pages allocated as bounce | |
1392 | + * buffers for doing I/O to pages residing above @page. By default | |
1393 | + * the block layer sets this to the highest numbered "low" memory page. | |
1394 | + **/ | |
1395 | +void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) | |
1396 | +{ | |
1397 | + unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT; | |
1398 | + unsigned long mb = dma_addr >> 20; | |
1399 | + static request_queue_t *old_q; | |
1400 | + | |
1401 | + /* | |
1402 | + * keep this for debugging for now... | |
1403 | + */ | |
1404 | + if (dma_addr != BLK_BOUNCE_HIGH && q != old_q) { | |
1405 | + old_q = q; | |
1406 | + printk("blk: queue %p, ", q); | |
1407 | + if (dma_addr == BLK_BOUNCE_ANY) | |
1408 | + printk("no I/O memory limit\n"); | |
1409 | + else | |
1410 | + printk("I/O limit %luMb (mask 0x%Lx)\n", mb, | |
1411 | + (long long) dma_addr); | |
1412 | + } | |
1413 | + | |
1414 | + q->bounce_pfn = bounce_pfn; | |
1415 | +} | |
1416 | + | |
1417 | + | |
1418 | +/* | |
1419 | + * can we merge the two segments, or do we need to start a new one? | |
1420 | + */ | |
1421 | +inline int blk_seg_merge_ok(struct buffer_head *bh, struct buffer_head *nxt) | |
1422 | +{ | |
1423 | + /* | |
1424 | + * if bh and nxt are contigous and don't cross a 4g boundary, it's ok | |
1425 | + */ | |
1426 | + if (BH_CONTIG(bh, nxt) && BH_PHYS_4G(bh, nxt)) | |
1427 | + return 1; | |
1428 | + | |
1429 | + return 0; | |
1430 | +} | |
1431 | + | |
1432 | static inline int ll_new_segment(request_queue_t *q, struct request *req, int max_segments) | |
1433 | { | |
1434 | if (req->nr_segments < max_segments) { | |
1435 | @@ -250,16 +303,18 @@ | |
1436 | static int ll_back_merge_fn(request_queue_t *q, struct request *req, | |
1437 | struct buffer_head *bh, int max_segments) | |
1438 | { | |
1439 | - if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data) | |
1440 | + if (blk_seg_merge_ok(req->bhtail, bh)) | |
1441 | return 1; | |
1442 | + | |
1443 | return ll_new_segment(q, req, max_segments); | |
1444 | } | |
1445 | ||
1446 | static int ll_front_merge_fn(request_queue_t *q, struct request *req, | |
1447 | struct buffer_head *bh, int max_segments) | |
1448 | { | |
1449 | - if (bh->b_data + bh->b_size == req->bh->b_data) | |
1450 | + if (blk_seg_merge_ok(bh, req->bh)) | |
1451 | return 1; | |
1452 | + | |
1453 | return ll_new_segment(q, req, max_segments); | |
1454 | } | |
1455 | ||
1456 | @@ -268,9 +323,9 @@ | |
1457 | { | |
1458 | int total_segments = req->nr_segments + next->nr_segments; | |
1459 | ||
1460 | - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) | |
1461 | + if (blk_seg_merge_ok(req->bhtail, next->bh)) | |
1462 | total_segments--; | |
1463 | - | |
1464 | + | |
1465 | if (total_segments > max_segments) | |
1466 | return 0; | |
1467 | ||
1468 | @@ -444,6 +499,8 @@ | |
1469 | */ | |
1470 | q->plug_device_fn = generic_plug_device; | |
1471 | q->head_active = 1; | |
1472 | + | |
1473 | + blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); | |
1474 | } | |
1475 | ||
1476 | #define blkdev_free_rq(list) list_entry((list)->next, struct request, queue); | |
1477 | @@ -540,7 +597,7 @@ | |
1478 | if (q->rq[rw].count == 0) | |
1479 | schedule(); | |
1480 | spin_lock_irq(&io_request_lock); | |
1481 | - rq = get_request(q,rw); | |
1482 | + rq = get_request(q, rw); | |
1483 | spin_unlock_irq(&io_request_lock); | |
1484 | } while (rq == NULL); | |
1485 | remove_wait_queue(&q->wait_for_requests[rw], &wait); | |
1486 | @@ -594,9 +651,14 @@ | |
1487 | printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n"); | |
1488 | } | |
1489 | ||
1490 | -/* Return up to two hd_structs on which to do IO accounting for a given | |
1491 | - * request. On a partitioned device, we want to account both against | |
1492 | - * the partition and against the whole disk. */ | |
1493 | +#ifdef CONFIG_BLK_STATS | |
1494 | +/* | |
1495 | + * Return up to two hd_structs on which to do IO accounting for a given | |
1496 | + * request. | |
1497 | + * | |
1498 | + * On a partitioned device, we want to account both against the partition | |
1499 | + * and against the whole disk. | |
1500 | + */ | |
1501 | static void locate_hd_struct(struct request *req, | |
1502 | struct hd_struct **hd1, | |
1503 | struct hd_struct **hd2) | |
1504 | @@ -611,22 +673,26 @@ | |
1505 | /* Mask out the partition bits: account for the entire disk */ | |
1506 | int devnr = MINOR(req->rq_dev) >> gd->minor_shift; | |
1507 | int whole_minor = devnr << gd->minor_shift; | |
1508 | + | |
1509 | *hd1 = &gd->part[whole_minor]; | |
1510 | if (whole_minor != MINOR(req->rq_dev)) | |
1511 | *hd2= &gd->part[MINOR(req->rq_dev)]; | |
1512 | } | |
1513 | } | |
1514 | ||
1515 | -/* Round off the performance stats on an hd_struct. The average IO | |
1516 | - * queue length and utilisation statistics are maintained by observing | |
1517 | - * the current state of the queue length and the amount of time it has | |
1518 | - * been in this state for. Normally, that accounting is done on IO | |
1519 | - * completion, but that can result in more than a second's worth of IO | |
1520 | - * being accounted for within any one second, leading to >100% | |
1521 | - * utilisation. To deal with that, we do a round-off before returning | |
1522 | - * the results when reading /proc/partitions, accounting immediately for | |
1523 | - * all queue usage up to the current jiffies and restarting the counters | |
1524 | - * again. */ | |
1525 | +/* | |
1526 | + * Round off the performance stats on an hd_struct. | |
1527 | + * | |
1528 | + * The average IO queue length and utilisation statistics are maintained | |
1529 | + * by observing the current state of the queue length and the amount of | |
1530 | + * time it has been in this state for. | |
1531 | + * Normally, that accounting is done on IO completion, but that can result | |
1532 | + * in more than a second's worth of IO being accounted for within any one | |
1533 | + * second, leading to >100% utilisation. To deal with that, we do a | |
1534 | + * round-off before returning the results when reading /proc/partitions, | |
1535 | + * accounting immediately for all queue usage up to the current jiffies and | |
1536 | + * restarting the counters again. | |
1537 | + */ | |
1538 | void disk_round_stats(struct hd_struct *hd) | |
1539 | { | |
1540 | unsigned long now = jiffies; | |
1541 | @@ -639,7 +705,6 @@ | |
1542 | hd->last_idle_time = now; | |
1543 | } | |
1544 | ||
1545 | - | |
1546 | static inline void down_ios(struct hd_struct *hd) | |
1547 | { | |
1548 | disk_round_stats(hd); | |
1549 | @@ -690,6 +755,7 @@ | |
1550 | void req_new_io(struct request *req, int merge, int sectors) | |
1551 | { | |
1552 | struct hd_struct *hd1, *hd2; | |
1553 | + | |
1554 | locate_hd_struct(req, &hd1, &hd2); | |
1555 | if (hd1) | |
1556 | account_io_start(hd1, req, merge, sectors); | |
1557 | @@ -697,15 +763,29 @@ | |
1558 | account_io_start(hd2, req, merge, sectors); | |
1559 | } | |
1560 | ||
1561 | +void req_merged_io(struct request *req) | |
1562 | +{ | |
1563 | + struct hd_struct *hd1, *hd2; | |
1564 | + | |
1565 | + locate_hd_struct(req, &hd1, &hd2); | |
1566 | + if (hd1) | |
1567 | + down_ios(hd1); | |
1568 | + if (hd2) | |
1569 | + down_ios(hd2); | |
1570 | +} | |
1571 | + | |
1572 | void req_finished_io(struct request *req) | |
1573 | { | |
1574 | struct hd_struct *hd1, *hd2; | |
1575 | + | |
1576 | locate_hd_struct(req, &hd1, &hd2); | |
1577 | if (hd1) | |
1578 | account_io_end(hd1, req); | |
1579 | if (hd2) | |
1580 | account_io_end(hd2, req); | |
1581 | } | |
1582 | +EXPORT_SYMBOL(req_finished_io); | |
1583 | +#endif /* CONFIG_BLK_STATS */ | |
1584 | ||
1585 | /* | |
1586 | * add-request adds a request to the linked list. | |
1587 | @@ -764,7 +844,6 @@ | |
1588 | int max_segments) | |
1589 | { | |
1590 | struct request *next; | |
1591 | - struct hd_struct *hd1, *hd2; | |
1592 | ||
1593 | next = blkdev_next_request(req); | |
1594 | if (req->sector + req->nr_sectors != next->sector) | |
1595 | @@ -791,12 +870,8 @@ | |
1596 | ||
1597 | /* One last thing: we have removed a request, so we now have one | |
1598 | less expected IO to complete for accounting purposes. */ | |
1599 | + req_merged_io(req); | |
1600 | ||
1601 | - locate_hd_struct(req, &hd1, &hd2); | |
1602 | - if (hd1) | |
1603 | - down_ios(hd1); | |
1604 | - if (hd2) | |
1605 | - down_ios(hd2); | |
1606 | blkdev_release_request(next); | |
1607 | } | |
1608 | ||
1609 | @@ -866,9 +941,7 @@ | |
1610 | * driver. Create a bounce buffer if the buffer data points into | |
1611 | * high memory - keep the original buffer otherwise. | |
1612 | */ | |
1613 | -#if CONFIG_HIGHMEM | |
1614 | - bh = create_bounce(rw, bh); | |
1615 | -#endif | |
1616 | + bh = blk_queue_bounce(q, rw, bh); | |
1617 | ||
1618 | /* look for a free request. */ | |
1619 | /* | |
1620 | @@ -900,7 +973,6 @@ | |
1621 | insert_here = &req->queue; | |
1622 | break; | |
1623 | } | |
1624 | - elevator->elevator_merge_cleanup_fn(q, req, count); | |
1625 | req->bhtail->b_reqnext = bh; | |
1626 | req->bhtail = bh; | |
1627 | req->nr_sectors = req->hard_nr_sectors += count; | |
1628 | @@ -915,11 +987,15 @@ | |
1629 | insert_here = req->queue.prev; | |
1630 | break; | |
1631 | } | |
1632 | - elevator->elevator_merge_cleanup_fn(q, req, count); | |
1633 | bh->b_reqnext = req->bh; | |
1634 | req->bh = bh; | |
1635 | + /* | |
1636 | + * may not be valid, but queues not having bounce | |
1637 | + * enabled for highmem pages must not look at | |
1638 | + * ->buffer anyway | |
1639 | + */ | |
1640 | req->buffer = bh->b_data; | |
1641 | - req->current_nr_sectors = count; | |
1642 | + req->current_nr_sectors = req->hard_cur_sectors = count; | |
1643 | req->sector = req->hard_sector = sector; | |
1644 | req->nr_sectors = req->hard_nr_sectors += count; | |
1645 | blk_started_io(count); | |
1646 | @@ -978,7 +1054,7 @@ | |
1647 | req->errors = 0; | |
1648 | req->hard_sector = req->sector = sector; | |
1649 | req->hard_nr_sectors = req->nr_sectors = count; | |
1650 | - req->current_nr_sectors = count; | |
1651 | + req->current_nr_sectors = req->hard_cur_sectors = count; | |
1652 | req->nr_segments = 1; /* Always 1 for a new request. */ | |
1653 | req->nr_hw_segments = 1; /* Always 1 for a new request. */ | |
1654 | req->buffer = bh->b_data; | |
1655 | @@ -1286,6 +1362,7 @@ | |
1656 | req->nr_sectors = req->hard_nr_sectors; | |
1657 | ||
1658 | req->current_nr_sectors = bh->b_size >> 9; | |
1659 | + req->hard_cur_sectors = req->current_nr_sectors; | |
1660 | if (req->nr_sectors < req->current_nr_sectors) { | |
1661 | req->nr_sectors = req->current_nr_sectors; | |
1662 | printk("end_request: buffer-list destroyed\n"); | |
1663 | @@ -1324,6 +1401,9 @@ | |
1664 | memset(max_readahead, 0, sizeof(max_readahead)); | |
1665 | memset(max_sectors, 0, sizeof(max_sectors)); | |
1666 | ||
1667 | + blk_max_low_pfn = max_low_pfn - 1; | |
1668 | + blk_max_pfn = max_pfn - 1; | |
1669 | + | |
1670 | #ifdef CONFIG_AMIGA_Z2RAM | |
1671 | z2_init(); | |
1672 | #endif | |
1673 | @@ -1439,5 +1519,9 @@ | |
1674 | EXPORT_SYMBOL(blk_queue_make_request); | |
1675 | EXPORT_SYMBOL(generic_make_request); | |
1676 | EXPORT_SYMBOL(blkdev_release_request); | |
1677 | -EXPORT_SYMBOL(req_finished_io); | |
1678 | EXPORT_SYMBOL(generic_unplug_device); | |
1679 | +EXPORT_SYMBOL(blk_queue_bounce_limit); | |
1680 | +EXPORT_SYMBOL(blk_max_low_pfn); | |
1681 | +EXPORT_SYMBOL(blk_max_pfn); | |
1682 | +EXPORT_SYMBOL(blk_seg_merge_ok); | |
1683 | +EXPORT_SYMBOL(blk_nohighio); | |
1684 | diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/include/linux/bootmem.h linux-2.4.20/include/linux/bootmem.h | |
1685 | --- linux-2.4.19/include/linux/bootmem.h 2001-11-22 19:47:23.000000000 +0000 | |
1686 | +++ linux-2.4.20/include/linux/bootmem.h 2002-10-29 11:18:49.000000000 +0000 | |
1687 | @@ -16,6 +16,7 @@ | |
1688 | ||
1689 | extern unsigned long max_low_pfn; | |
1690 | extern unsigned long min_low_pfn; | |
1691 | +extern unsigned long max_pfn; | |
1692 | ||
1693 | /* | |
1694 | * node_bootmem_map is a map pointer - the bits represent all physical |