Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* |
2 | * Project: S.Ha.R.K. |
||
3 | * |
||
4 | * Coordinators: |
||
5 | * Giorgio Buttazzo <giorgio@sssup.it> |
||
6 | * Paolo Gai <pj@gandalf.sssup.it> |
||
7 | * |
||
8 | * Authors : |
||
9 | * Paolo Gai <pj@gandalf.sssup.it> |
||
10 | * Massimiliano Giorgi <massy@gandalf.sssup.it> |
||
11 | * Luca Abeni <luca@gandalf.sssup.it> |
||
12 | * (see the web pages for full authors list) |
||
13 | * |
||
14 | * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
||
15 | * |
||
16 | * http://www.sssup.it |
||
17 | * http://retis.sssup.it |
||
18 | * http://shark.sssup.it |
||
19 | */ |
||
20 | |||
21 | /*************************************** |
||
22 | |||
23 | CVS : $Id: ide.c,v 1.1.1.1 2002-03-29 14:12:49 pj Exp $ |
||
24 | |||
25 | Revision: $Revision: 1.1.1.1 $ |
||
26 | |||
27 | Last update: $Date: 2002-03-29 14:12:49 $ |
||
28 | |||
29 | This module contains IDE initialization, IDE glue between |
||
30 | the "block device" module and the IDE low level module and some |
||
31 | usefull function used by the low level module. |
||
32 | |||
33 | ***************************************/ |
||
34 | |||
35 | /* |
||
36 | * Copyright (C) 19992,2000 Massimiliano Giorgi |
||
37 | * |
||
38 | * This program is free software; you can redistribute it and/or modify |
||
39 | * it under the terms of the GNU General Public License as published by |
||
40 | * the Free Software Foundation; either version 2 of the License, or |
||
41 | * (at your option) any later version. |
||
42 | * |
||
43 | * This program is distributed in the hope that it will be useful, |
||
44 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
45 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
46 | * GNU General Public License for more details. |
||
47 | * |
||
48 | * You should have received a copy of the GNU General Public License |
||
49 | * along with this program; if not, write to the Free Software |
||
50 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
51 | * |
||
52 | */ |
||
53 | |||
54 | #include "glue.h" |
||
55 | |||
56 | #include <fs/sysmacro.h> |
||
57 | #include <fs/major.h> |
||
58 | #include <fs/magic.h> |
||
59 | #include <fs/bdevinit.h> |
||
60 | #include <fs/assert.h> |
||
61 | #include <fs/maccess.h> |
||
62 | #include <fs/assert.h> |
||
63 | |||
64 | #include "sysind.h" |
||
65 | #include "bdev.h" |
||
66 | #include "phdsk.h" |
||
67 | #include "lodsk.h" |
||
68 | #include "ide.h" |
||
69 | #include "idereq.h" |
||
70 | |||
71 | /* |
||
72 | * FLAGS |
||
73 | */ |
||
74 | |||
75 | /*+ if defined: scan for device on interface also if soft reset fail +*/ |
||
76 | #define FORCE_SCANNING 1 |
||
77 | //#undef FORCE_SCANNING |
||
78 | |||
79 | /*+ if defined: use PIO (polled) I/O on all interfaces, disable DMA +*/ |
||
80 | #define FORCE_PIOMODE 1 |
||
81 | //#undef FORCE_PIOMODE |
||
82 | |||
83 | /*+ if 1: search only master device (no slave) +*/ |
||
84 | /*+ if 0: search master and slave device +*/ |
||
85 | #define ONLY_MASTER 1 |
||
86 | |||
87 | /* |
||
88 | * DEBUG |
||
89 | */ |
||
90 | |||
91 | /*+ if defined: trace initialization ++*/ |
||
92 | #define TRACE_INIT KERN_DEBUG |
||
93 | #undef TRACE_INIT |
||
94 | |||
95 | /*+ if defined: trace ide_scan() [to find devices] +*/ |
||
96 | #define TRACE_IDESCAN KERN_DEBUG |
||
97 | #undef TRACE_IDESCAN |
||
98 | |||
99 | /*+ if defined: trace ide_scandisk() [to find logical layout] +*/ |
||
100 | #define TRACE_IDESCANDEV KERN_DEBUG |
||
101 | #undef TRACE_IDESCANDEV |
||
102 | |||
103 | /**/ |
||
104 | |||
105 | /*+ these are debug macros... +*/ |
||
106 | |||
107 | #ifdef TRACE_INIT |
||
108 | #define printk0(fmt,args...) \ |
||
109 | printk(TRACE_INIT "ide_init: " fmt,##args) |
||
110 | #else |
||
111 | #define printk0(fmt,args...) |
||
112 | #endif |
||
113 | |||
114 | #ifdef TRACE_IDESCAN |
||
115 | #define printk1(fmt,args...) \ |
||
116 | printk(TRACE_IDESCAN "ide_scan: " fmt,##args) |
||
117 | #else |
||
118 | #define printk1(fmt,args...) |
||
119 | #endif |
||
120 | |||
121 | #ifdef TRACE_IDESCANDEV |
||
122 | #define printk2(fmt,args...) \ |
||
123 | printk(TRACE_IDESCANDEV "ide_scandisk: " fmt,##args) |
||
124 | #else |
||
125 | #define printk2(fmt,args...) |
||
126 | #endif |
||
127 | |||
128 | /* |
||
129 | * |
||
130 | * |
||
131 | */ |
||
132 | |||
133 | /*+ Name used by this block device +*/ |
||
134 | static char device_name[]="ide"; |
||
135 | |||
136 | // /dev/ide/hd-i0mp1 |
||
137 | |||
138 | /*+ Mantains informatio about a single interface +*/ |
||
139 | /* warning: must not cross 4KBytes boundaries (required for DMA operations) */ |
||
140 | struct ideinfo ide[MAXIDEINTERFACES]={{0}}; |
||
141 | //struct ideinfo ide[MAXIDEINTERFACES] __attribute__((nocommon)); |
||
142 | //struct ideinfo ide[MAXIDEINTERFACES] __attribute__((section("ide_section")))= |
||
143 | //{0}; |
||
144 | |||
145 | /*+ Mantains information about every physical device +*/ |
||
146 | static struct ideminorinfo mtable[MAXIDEMINOR]; |
||
147 | |||
148 | /* |
||
149 | * |
||
150 | * |
||
151 | * |
||
152 | */ |
||
153 | |||
154 | //#ifndef NDEBUG |
||
155 | void ide_dump_status(void) |
||
156 | { |
||
157 | int i; |
||
158 | |||
159 | printk(KERN_INFO "ide block device status:"); |
||
160 | for (i=0;i<MAXIDEINTERFACES;i++) |
||
161 | if (!is_ide_free(i)) { |
||
162 | printk(KERN_INFO " ide%i:",i); |
||
163 | printk(KERN_INFO " errors: %i",ide[i].errors); |
||
164 | } |
||
165 | } |
||
166 | //#endif |
||
167 | |||
168 | /* |
||
169 | * how parameters are mapped to device minor number: |
||
170 | * |
||
171 | * 7 6 5 4 3 2 1 0 |
||
172 | * --------------------------------- |
||
173 | * I . . I I . . . I |
||
174 | * --------------------------------- |
||
175 | * ^ ^ ^ |
||
176 | * I I I-- logical disk (aka partition) |
||
177 | * I I------------ drive id (aka master,slave) |
||
178 | * I-------------------- interface |
||
179 | */ |
||
180 | |||
181 | /*++++++++++++++++++++++++++++++++++++++ |
||
182 | |||
183 | Convert an interface id, driver id, logical disk to a device id. |
||
184 | |||
185 | __dev_t idemakedev |
||
186 | return a device id |
||
187 | |||
188 | int ideif |
||
189 | ide interface sequential number |
||
190 | |||
191 | int drv |
||
192 | ide channel (IDE_MASTER, IDE_SLAVE) |
||
193 | |||
194 | int lodsk |
||
195 | logical disk (aka partition) on than device |
||
196 | ++++++++++++++++++++++++++++++++++++++*/ |
||
197 | |||
198 | static __inline__ __dev_t idemakedev(int ideif,int drv,int lodsk) |
||
199 | { |
||
200 | return makedev(MAJOR_B_IDE,((ideif&0x7)<<5)|((drv&0x1)<<4)|(lodsk&0xf)); |
||
201 | } |
||
202 | |||
203 | /*++++++++++++++++++++++++++++++++++++++ |
||
204 | |||
205 | Extract an interface id from a device id. |
||
206 | |||
207 | int idehwif |
||
208 | return an interface id |
||
209 | |||
210 | __dev_t dev |
||
211 | device id to parse |
||
212 | ++++++++++++++++++++++++++++++++++++++*/ |
||
213 | |||
214 | static __inline__ int idehwif(__dev_t dev) |
||
215 | { |
||
216 | return minor(dev)>>5; |
||
217 | } |
||
218 | |||
219 | /*++++++++++++++++++++++++++++++++++++++ |
||
220 | |||
221 | Extract a drive id from a device id. |
||
222 | |||
223 | int idedriveid |
||
224 | return a device id |
||
225 | |||
226 | __dev_t dev |
||
227 | device id to parse |
||
228 | ++++++++++++++++++++++++++++++++++++++*/ |
||
229 | |||
230 | static __inline__ int idedriveid(__dev_t dev) |
||
231 | { |
||
232 | return (minor(dev)&0x10)?1:0; |
||
233 | } |
||
234 | |||
235 | /*++++++++++++++++++++++++++++++++++++++ |
||
236 | |||
237 | Extract a logical disk id from a device id. |
||
238 | |||
239 | int idelodsk |
||
240 | return a logical disk id |
||
241 | |||
242 | __dev_t dev |
||
243 | device id to parse |
||
244 | ++++++++++++++++++++++++++++++++++++++*/ |
||
245 | |||
246 | static __inline__ int idelodsk(__dev_t dev) |
||
247 | { |
||
248 | return minor(dev)&0xf; |
||
249 | } |
||
250 | |||
251 | /*++++++++++++++++++++++++++++++++++++++ |
||
252 | |||
253 | Extract the minor part of a device number. |
||
254 | |||
255 | int idemindex |
||
256 | return a device minor number |
||
257 | |||
258 | __dev_t dev |
||
259 | device id to parse |
||
260 | ++++++++++++++++++++++++++++++++++++++*/ |
||
261 | |||
262 | static __inline__ int idemindex(__dev_t dev) |
||
263 | { |
||
264 | return minor(dev); |
||
265 | } |
||
266 | |||
267 | |||
268 | /*++++++++++++++++++++++++++++++++++++++ |
||
269 | |||
270 | Parse a device minor number from a device id and a logical disk id. |
||
271 | |||
272 | int idemindexext |
||
273 | return a device minor number |
||
274 | |||
275 | __dev_t dev |
||
276 | device id to parse |
||
277 | |||
278 | int lodsk |
||
279 | logical disk id to parse |
||
280 | ++++++++++++++++++++++++++++++++++++++*/ |
||
281 | |||
282 | static __inline__ int idemindexext(__dev_t dev, int lodsk) |
||
283 | { |
||
284 | return minor(dev)+(lodsk&0xf); |
||
285 | } |
||
286 | |||
287 | /* --- */ |
||
288 | |||
289 | //#ifndef NDEBUG |
||
290 | int ide_dump_startsize(__dev_t dev, __blkcnt_t *start, __blkcnt_t *size) |
||
291 | { |
||
292 | int i; |
||
293 | if (major(dev)!=MAJOR_B_IDE) return -1; |
||
294 | i=idemindex(dev); |
||
295 | if (mtable[i].used) { |
||
296 | *start=mtable[i].start; |
||
297 | *size=mtable[i].size; |
||
298 | return 0; |
||
299 | } |
||
300 | return -1; |
||
301 | } |
||
302 | //#endif |
||
303 | |||
304 | /* |
||
305 | * |
||
306 | * to manage struct ata_diskid |
||
307 | * |
||
308 | */ |
||
309 | |||
310 | /*++++++++++++++++++++++++++++++++++++++ |
||
311 | |||
312 | Dump, using printk(), the "important" information returned by an ide |
||
313 | device in response to an ATA IDENTIFY request. |
||
314 | |||
315 | struct ata_diskid *ptr |
||
316 | pointer to the structure returned by an IDENTIFY command |
||
317 | |||
318 | struct ide_diskinfo *info |
||
319 | pointer to the disk information structure (build decoding an |
||
320 | ata_diskid structure) |
||
321 | ++++++++++++++++++++++++++++++++++++++*/ |
||
322 | |||
323 | static void ide_dump_diskid(struct ata_diskid *ptr, |
||
324 | struct ide_diskinfo *info) |
||
325 | { |
||
326 | char atabuf[256]; |
||
327 | int i,j; |
||
328 | |||
329 | if (is_ATA4(ptr)||is_ATA3(ptr)||is_ATA2(ptr)||is_ATA(ptr)) { |
||
330 | i=0; |
||
331 | if (is_ATA(ptr)) { |
||
332 | atabuf[i++]='1'; |
||
333 | atabuf[i++]=' '; |
||
334 | } |
||
335 | if (is_ATA2(ptr)) { |
||
336 | atabuf[i++]='2'; |
||
337 | atabuf[i++]=' '; |
||
338 | } |
||
339 | if (is_ATA3(ptr)) { |
||
340 | atabuf[i++]='3'; |
||
341 | atabuf[i++]=' '; |
||
342 | } |
||
343 | if (is_ATA4(ptr)) { |
||
344 | atabuf[i++]='4'; |
||
345 | atabuf[i++]=' '; |
||
346 | } |
||
347 | atabuf[i++]='\0'; |
||
348 | } else |
||
349 | /* actualy only ATA disk are recognized */ |
||
350 | sprintf(atabuf,"?"); |
||
351 | |||
352 | printk(IDELOG " device : hard disk"); |
||
353 | printk(IDELOG " model : %s",ptr->model); |
||
354 | printk(IDELOG " serial : %s",ptr->serial); |
||
355 | printk(IDELOG " firmware rev : %s",ptr->firmware); |
||
356 | printk(IDELOG " default C/H/S : %i/%i/%i", |
||
357 | ptr->def_cyls,ptr->def_heads,ptr->def_sects); |
||
358 | printk(IDELOG " total capacity : ~%4.3f GBytes", |
||
359 | (double)ptr->lba_capacity/(1024.0*1024.0*2.0)); |
||
360 | printk(IDELOG " ATA : %s",atabuf); |
||
361 | printk(IDELOG " LBA : %s",is_LBAcapable(ptr)?"yes":"no"); |
||
362 | |||
363 | i=0; |
||
364 | if (info->max_pio_mode<0) strcpy(atabuf,"none"); |
||
365 | else { |
||
366 | for (j=info->max_pio_mode;j>=0;j--) { |
||
367 | strcpy(atabuf+i,"pio"); i+=3; |
||
368 | atabuf[i++]=j+'0'; |
||
369 | atabuf[i++]=' '; |
||
370 | } |
||
371 | atabuf[i++]='\0'; |
||
372 | } |
||
373 | printk(IDELOG " PIO modes : %s",atabuf); |
||
374 | |||
375 | i=0; |
||
376 | if (info->max_dma_mode<0) strcpy(atabuf,"none"); |
||
377 | else { |
||
378 | for (j=info->max_dma_mode;j>=0;j--) { |
||
379 | strcpy(atabuf+i,"mword"); i+=5; |
||
380 | atabuf[i++]=j+'0'; |
||
381 | atabuf[i++]=' '; |
||
382 | } |
||
383 | atabuf[i++]='\0'; |
||
384 | } |
||
385 | printk(IDELOG " DMA modes : %s",atabuf); |
||
386 | |||
387 | i=0; |
||
388 | if (info->max_udma_mode<0) strcpy(atabuf,"none"); |
||
389 | else { |
||
390 | for (j=info->max_udma_mode;j>=0;j--) { |
||
391 | strcpy(atabuf+i,"udma"); i+=4; |
||
392 | atabuf[i++]=j+'0'; |
||
393 | atabuf[i++]=' '; |
||
394 | } |
||
395 | atabuf[i++]='\0'; |
||
396 | } |
||
397 | printk(IDELOG " UDMA modes : %s",atabuf); |
||
398 | } |
||
399 | |||
400 | /*++++++++++++++++++++++++++++++++++++++ |
||
401 | |||
402 | Dump, using printk(), the "important" information returned by an ide |
||
403 | device in response to an ATAPI PACKET IDENTIFY request. |
||
404 | |||
405 | struct atapi_diskid *ptr |
||
406 | pointer to the structure returned by a PACKET IDENTIFY command |
||
407 | ++++++++++++++++++++++++++++++++++++++*/ |
||
408 | |||
409 | static void ide_dump_atapidiskid(struct atapi_diskid *ptr) |
||
410 | { |
||
411 | char atabuf[16]; |
||
412 | //__uint8_t *p; |
||
413 | char *dev; |
||
414 | int i=0; |
||
415 | |||
416 | if (is_ATAPIdevice(ptr)) { |
||
417 | strcpy(atabuf,"ATAPI "); |
||
418 | i=6; |
||
419 | } |
||
420 | |||
421 | if (is_ATA4(ptr)||is_ATA3(ptr)||is_ATA2(ptr)||is_ATA(ptr)) { |
||
422 | if (is_ATA(ptr)) { |
||
423 | atabuf[i++]='1'; |
||
424 | atabuf[i++]=' '; |
||
425 | } |
||
426 | if (is_ATA2(ptr)) { |
||
427 | atabuf[i++]='2'; |
||
428 | atabuf[i++]=' '; |
||
429 | } |
||
430 | if (is_ATA3(ptr)) { |
||
431 | atabuf[i++]='3'; |
||
432 | atabuf[i++]=' '; |
||
433 | } |
||
434 | if (is_ATA4(ptr)) { |
||
435 | atabuf[i++]='4'; |
||
436 | atabuf[i++]=' '; |
||
437 | } |
||
438 | atabuf[i++]='\0'; |
||
439 | } else { |
||
440 | /* actualy only ATA disk are recognized */ |
||
441 | atabuf[i++]='?'; |
||
442 | atabuf[i++]='\0'; |
||
443 | } |
||
444 | |||
445 | if (is_directdev(ptr)) dev="direct"; |
||
446 | else if (is_sequentialdev(ptr)) dev="sequential"; |
||
447 | else if (is_printerdev(ptr)) dev="printer"; |
||
448 | else if (is_processordev(ptr)) dev="processor"; |
||
449 | else if (is_writeoncedev(ptr)) dev="write once"; |
||
450 | else if (is_cdromdev(ptr)) dev="cd-rom"; |
||
451 | else if (is_scannerdev(ptr)) dev="scanner"; |
||
452 | else if (is_opticalmemorydev(ptr)) dev="optical memory"; |
||
453 | else if (is_mediachengerdev(ptr)) dev="media changer"; |
||
454 | else if (is_communicatordev(ptr)) dev="communicator"; |
||
455 | else if (is_arraydev(ptr)) dev="array"; |
||
456 | else dev="?"; |
||
457 | |||
458 | printk(IDELOG " device : %s",dev); |
||
459 | printk(IDELOG " model : %s",ptr->model); |
||
460 | printk(IDELOG " serial : %s",ptr->serial); |
||
461 | printk(IDELOG " firmware rev : %s",ptr->firmware); |
||
462 | printk(IDELOG " ATA : %s",atabuf); |
||
463 | } |
||
464 | |||
465 | /* |
||
466 | * |
||
467 | * Interface the "block device" module to the low-level routine |
||
468 | * |
||
469 | */ |
||
470 | |||
471 | /* |
||
472 | void dump_buffer(__uint8_t *buf) |
||
473 | { |
||
474 | int i; |
||
475 | for (i=0;i<512;i++) { |
||
476 | cprintf("%02x ",(int)*(buf+i)); |
||
477 | if (i%16==15) cprintf("\n"); |
||
478 | } |
||
479 | } |
||
480 | */ |
||
481 | |||
482 | |||
483 | /*++++++++++++++++++++++++++++++++++++++ |
||
484 | |||
485 | Try to lock a device. |
||
486 | (A device can be locked if the device is a partition and the whole |
||
487 | disk is not locked or if the device is the whole disk and any partititions |
||
488 | have been locked). |
||
489 | |||
490 | int ide_trylock |
||
491 | return ?_ERR on error, ?_OK on success and, ?_CANT on failure |
||
492 | |||
493 | __devt_t device |
||
494 | device to use |
||
495 | ++++++++++++++++++++++++++++++++++++++*/ |
||
496 | |||
497 | static int ide_trylock(__dev_t device) |
||
498 | { |
||
499 | int i,ind,ind2; |
||
500 | |||
501 | ind=idemindex(device); |
||
502 | assertk(ind>=0&&ind<MAXIDEMINOR); |
||
503 | |||
504 | if (!mtable[ind].used) return TRYLOCK_ERR; |
||
505 | |||
506 | if (mtable[ind].blocked) return TRYLOCK_CANT; |
||
507 | |||
508 | if (idelodsk(device)==0) { |
||
509 | for (i=1;;i++) { |
||
510 | ind2=idemindex(idemakedev(idehwif(device),idedriveid(device),i)); |
||
511 | assertk(ind2>=0&&ind2<MAXIDEMINOR); |
||
512 | if (ind2==ind) { |
||
513 | mtable[ind].blocked=1; |
||
514 | return TRYLOCK_OK; |
||
515 | } |
||
516 | if (!mtable[ind2].used) continue; |
||
517 | if (mtable[ind2].blocked) return TRYLOCK_CANT; |
||
518 | } |
||
519 | } |
||
520 | |||
521 | ind2=idemindex(idemakedev(idehwif(device),idedriveid(device),0)); |
||
522 | assertk(ind2>=0&&ind2<MAXIDEMINOR); |
||
523 | assertk(mtable[ind2].used==1); |
||
524 | |||
525 | if (mtable[ind2].blocked) return TRYLOCK_CANT; |
||
526 | |||
527 | mtable[ind].blocked=1; |
||
528 | return TRYLOCK_OK; |
||
529 | } |
||
530 | |||
531 | static int ide_tryunlock(__dev_t device) |
||
532 | { |
||
533 | int ind; |
||
534 | |||
535 | ind=idemindex(device); |
||
536 | assertk(ind>=0&&ind<MAXIDEMINOR); |
||
537 | |||
538 | if (!mtable[ind].used) return TRYUNLOCK_ERR; |
||
539 | if (!mtable[ind].blocked) return TRYUNLOCK_ERR; |
||
540 | mtable[ind].blocked=0; |
||
541 | return TRYUNLOCK_OK; |
||
542 | } |
||
543 | |||
544 | /*++++++++++++++++++++++++++++++++++++++ |
||
545 | |||
546 | Read a block of data (sector) from a device into a buffer. |
||
547 | |||
548 | int bd_ide_read |
||
549 | return 0 on success, other values on error |
||
550 | |||
551 | __dev_t device |
||
552 | device id to read from |
||
553 | |||
554 | __blkcnt_t blocknum |
||
555 | block number to read |
||
556 | |||
557 | __uint8_t *buffer |
||
558 | buffer for the readed data |
||
559 | ++++++++++++++++++++++++++++++++++++++*/ |
||
560 | |||
561 | static int bd_ide_read(__dev_t device, __blkcnt_t blocknum, __uint8_t *buffer) |
||
562 | { |
||
563 | register int ideif=idehwif(device); |
||
564 | register int index=idemindex(device); |
||
565 | int res; |
||
566 | |||
567 | magic_assert(ide[ideif].magic,IDE_MAGIC, |
||
568 | "ide%i: interface overwritten",ideif); |
||
569 | magic_assert(mtable[index].magic,IDE_MAGIC_MINOR, |
||
570 | "ide%i: minor %i overwritten",ideif,minor(device)); |
||
571 | |||
572 | if (major(device)!=MAJOR_B_IDE) { |
||
573 | printk(IDEERRLOG "ide%i: major %i is not EIDE",ideif,major(device)); |
||
574 | return -1; |
||
575 | } |
||
576 | |||
577 | if (minor(device)>MAXIDEMINOR) { |
||
578 | printk(IDEERRLOG "ide%i: minor %i out of range",ideif,minor(device)); |
||
579 | return -1; |
||
580 | } |
||
581 | |||
582 | if (!mtable[index].used) { |
||
583 | printk(IDEERRLOG "ide%i: minor %i not present",ideif,minor(device)); |
||
584 | return -1; |
||
585 | } |
||
586 | |||
587 | //cprintf("index=%i\n",index); |
||
588 | //cprintf("blocknum=%li\n",(long)blocknum); |
||
589 | //cprintf("size=%li\n",(long)mtable[index].size); |
||
590 | //cprintf("start=%li\n",(long)mtable[index].start); |
||
591 | //cprintf("sizeof(size)=%i\n",sizeof(mtable[index].size)); |
||
592 | |||
593 | /* |
||
594 | if (blocknum<0||blocknum>=mtable[index].size) { |
||
595 | printk(IDEERRLOG "ide%i: request block out of range",ideif); |
||
596 | return -1; |
||
597 | } |
||
598 | */ |
||
599 | |||
600 | res=ide_read(ideif,idedriveid(device), |
||
601 | mtable[index].start+blocknum, |
||
602 | buffer); |
||
603 | |||
604 | //if (blocknum==0x9ea19) |
||
605 | // dump_buffer(buffer); |
||
606 | |||
607 | //cprintf("index=%i\n",index); |
||
608 | //cprintf("blocknum=%li\n",(long)blocknum); |
||
609 | //cprintf("size=%li\n",(long)mtable[index].size); |
||
610 | //cprintf("sizeof(size)=%i\n\n",sizeof(mtable[index].size)); |
||
611 | |||
612 | return res; |
||
613 | } |
||
614 | |||
615 | /*++++++++++++++++++++++++++++++++++++++ |
||
616 | |||
617 | Move the head on a specified cylinder. |
||
618 | |||
619 | int bd_ide_seek |
||
620 | return 0 on success, other values on error |
||
621 | |||
622 | __dev_t device |
||
623 | device id to read from |
||
624 | |||
625 | __blkcnt_t blocknum |
||
626 | block number to moving into |
||
627 | ++++++++++++++++++++++++++++++++++++++*/ |
||
628 | |||
629 | static int bd_ide_seek(__dev_t device, __blkcnt_t blocknum) |
||
630 | { |
||
631 | register int ideif=idehwif(device); |
||
632 | register int index=idemindex(device); |
||
633 | int res; |
||
634 | |||
635 | magic_assert(ide[ideif].magic,IDE_MAGIC, |
||
636 | "ide%i: interface overwritten",ideif); |
||
637 | magic_assert(mtable[index].magic,IDE_MAGIC_MINOR, |
||
638 | "ide%i: minor %i overwritten",ideif,minor(device)); |
||
639 | |||
640 | if (major(device)!=MAJOR_B_IDE) { |
||
641 | printk(IDEERRLOG "ide%i: major %i is not EIDE",ideif,major(device)); |
||
642 | return -1; |
||
643 | } |
||
644 | |||
645 | if (minor(device)>MAXIDEMINOR) { |
||
646 | printk(IDEERRLOG "ide%i: minor %i out of range",ideif,minor(device)); |
||
647 | return -1; |
||
648 | } |
||
649 | |||
650 | if (!mtable[index].used) { |
||
651 | printk(IDEERRLOG "ide%i: minor %i not present",ideif,minor(device)); |
||
652 | return -1; |
||
653 | } |
||
654 | |||
655 | res=ide_seek(ideif,idedriveid(device), |
||
656 | mtable[index].start+blocknum); |
||
657 | |||
658 | return res; |
||
659 | } |
||
660 | |||
661 | /*++++++++++++++++++++++++++++++++++++++ |
||
662 | |||
663 | Write a block of data (sector) from a buffer into a device (not yet |
||
664 | implemented, return always error). |
||
665 | |||
666 | int bd_ide_write |
||
667 | return 0 on success, other value on errors |
||
668 | |||
669 | __dev_t device |
||
670 | device id to write into |
||
671 | |||
672 | __blkcnt_t blocknum |
||
673 | block number to write |
||
674 | |||
675 | __uint8_t *buffer |
||
676 | buffer to write into |
||
677 | ++++++++++++++++++++++++++++++++++++++*/ |
||
678 | |||
679 | static int bd_ide_write(__dev_t device, __blkcnt_t blocknum, __uint8_t *buffer) |
||
680 | { |
||
681 | register int ideif=idehwif(device); |
||
682 | register int index=idemindex(device); |
||
683 | int res; |
||
684 | |||
685 | magic_assert(ide[ideif].magic,IDE_MAGIC, |
||
686 | "ide%i: interface overwritten",ideif); |
||
687 | magic_assert(mtable[index].magic,IDE_MAGIC_MINOR, |
||
688 | "ide%i: minor %i overwritten",ideif,minor(device)); |
||
689 | |||
690 | if (major(device)!=MAJOR_B_IDE) { |
||
691 | printk(IDEERRLOG "ide%i: major %i is not EIDE",ideif,major(device)); |
||
692 | return -1; |
||
693 | } |
||
694 | |||
695 | if (minor(device)>MAXIDEMINOR) { |
||
696 | printk(IDEERRLOG "ide%i: minor %i out of range",ideif,minor(device)); |
||
697 | return -1; |
||
698 | } |
||
699 | |||
700 | if (!mtable[index].used) { |
||
701 | printk(IDEERRLOG "ide%i: minor %i not present",ideif,minor(device)); |
||
702 | return -1; |
||
703 | } |
||
704 | |||
705 | res=ide_write(ideif,idedriveid(device), |
||
706 | mtable[index].start+blocknum, |
||
707 | buffer); |
||
708 | |||
709 | return res; |
||
710 | } |
||
711 | |||
712 | /* |
||
713 | * |
||
714 | * Initialization |
||
715 | * |
||
716 | */ |
||
717 | |||
718 | /*+ Data used to register the IDE module to the block device manager +*/ |
||
719 | static struct block_device_operations ide_operations={ |
||
720 | ide_trylock, |
||
721 | ide_tryunlock, |
||
722 | bd_ide_read, |
||
723 | bd_ide_seek, |
||
724 | bd_ide_write |
||
725 | }; |
||
726 | |||
727 | /* this information are saved from the initialization routine for |
||
728 | * futher reference |
||
729 | */ |
||
730 | |||
731 | /*+ initialization parameter (for the "glue" initialization) +*/ |
||
732 | void *ide_parm_initserver=NULL; |
||
733 | |||
734 | /*+ show information during startup? +*/ |
||
735 | int ide_showinfo_flag=0; |
||
736 | |||
737 | /*++++++++++++++++++++++++++++++++++++++ |
||
738 | |||
739 | This function try to register an IDE interface, scan for device and |
||
740 | identify the logical struct of the device |
||
741 | |||
742 | int ide_tryregister |
||
743 | return 0 on successe <0 on error |
||
744 | |||
745 | int port0 |
||
746 | first port of the ide interface (ide port) |
||
747 | |||
748 | int port1 |
||
749 | second port of the ide interface (control port) |
||
750 | |||
751 | int irq |
||
752 | irq of the ide interface |
||
753 | |||
754 | int dma |
||
755 | dma 16bits channel (if using not bus master mode) |
||
756 | |||
757 | int bmdma |
||
758 | port for the bus master dma operations |
||
759 | ++++++++++++++++++++++++++++++++++++++*/ |
||
760 | |||
761 | static int ide_tryregister(int port0, int port1, int irq, int dma, int bmdma) |
||
762 | { |
||
763 | int ideif,res,j; |
||
764 | |||
765 | ideif=ide_register(port0,port1,irq,dma,bmdma); |
||
766 | printk0("registering IDE at 0x%04x,0x%04x,%i,%i,0x%04x... ", |
||
767 | port0,port1,irq,dma,bmdma); |
||
768 | if (ideif>=0) { |
||
769 | res=ide_scan(ideif); |
||
770 | printk0("found %i peripheral(s)",res); |
||
771 | if (res>0) { |
||
772 | for (j=IDE_MASTER;j<=IDE_SLAVE;j++) { |
||
773 | if (ide[ideif].pdisk[j]!=NULL) { |
||
774 | printk0("scanning %s for logical layout", |
||
775 | j==IDE_MASTER?"master":"slave"); |
||
776 | ide_scandisk(ideif,j); |
||
777 | } |
||
778 | } |
||
779 | return 0; |
||
780 | } |
||
781 | return -1; |
||
782 | } else |
||
783 | printk0("registering failed"); |
||
784 | return -2; |
||
785 | } |
||
786 | |||
787 | /*++++++++++++++++++++++++++++++++++++++ |
||
788 | |||
789 | This function parse a string to find "command line options" for the |
||
790 | IDE subsystem; see source for comments. |
||
791 | |||
792 | int ide_scanparms |
||
793 | return 0 on success, other values on error |
||
794 | |||
795 | char *str |
||
796 | string to parse |
||
797 | ++++++++++++++++++++++++++++++++++++++*/ |
||
798 | |||
799 | static int ide_scanparms(char *str) |
||
800 | { |
||
801 | int port0,port1,irq,dma=-1,bmdma=-1; |
||
802 | char *ptr; |
||
803 | int ret; |
||
804 | |||
805 | /* available string options: |
||
806 | |||
807 | ide=port,sec_port,irq |
||
808 | example |
||
809 | "ide=0x1f0,0x3f0,14" |
||
810 | |||
811 | try to register this ide interface |
||
812 | */ |
||
813 | |||
814 | printk0("(start) searching for parameters"); |
||
815 | if (str==NULL) { |
||
816 | printk0("(end) searching for parameters"); |
||
817 | return 0; |
||
818 | } |
||
819 | |||
820 | ptr=str; |
||
821 | for (;;) { |
||
822 | ptr=strscn(ptr,"ide="); |
||
823 | if (ptr==NULL) return 0; |
||
824 | ret=sscanf(ptr,"ide=%x,%x,%i,%i,%x",&port0,&port1,&irq,&dma,&bmdma); |
||
825 | if (ret==3||ret==5) { |
||
826 | { |
||
827 | int len; |
||
828 | char *s; |
||
829 | s=strchr(ptr,' '); |
||
830 | if (s!=NULL) len=s-ptr+1; |
||
831 | else len=strlen(ptr); |
||
832 | memset(ptr,len,' '); |
||
833 | } |
||
834 | ide_tryregister(port0,port1,irq,dma,bmdma); |
||
835 | } |
||
836 | ptr++; |
||
837 | } |
||
838 | printk0("(end) searching for parameters"); |
||
839 | return 0; |
||
840 | } |
||
841 | |||
842 | /*++++++++++++++++++++++++++++++++++++++ |
||
843 | |||
844 | This function initialize the IDE subsystem; must be called before every |
||
845 | other function. |
||
846 | |||
847 | It initialize internal data structure, register itself to the bdev |
||
848 | (block dev) manager and try to initialize "standard" IDE interface; |
||
849 | non-standard ide interface can be initialize using the struct IDE_PARMS |
||
850 | (see include/fs/fsinit.h). |
||
851 | |||
852 | int ide_init |
||
853 | return 0 on success, other on failure |
||
854 | |||
855 | BDEV_PARMS *parms |
||
856 | pointer to a structure contains general and specific initialization |
||
857 | data |
||
858 | ++++++++++++++++++++++++++++++++++++++*/ |
||
859 | |||
860 | int ide_init(BDEV_PARMS *parms) |
||
861 | { |
||
862 | struct block_device bd; |
||
863 | __uint32_t addr; |
||
864 | int res; |
||
865 | int i; |
||
866 | |||
867 | printk0("START"); |
||
868 | |||
869 | init_idereq(); |
||
870 | printk0("init_idereq()... done"); |
||
871 | |||
872 | for (i=0;i<MAXIDEINTERFACES;i++) { |
||
873 | |||
874 | magic_set(ide[i].magic,IDE_MAGIC); |
||
875 | |||
876 | ide[i].server=NIL; |
||
877 | ide[i].io_port=0; |
||
878 | ide[i].io_port2=0; |
||
879 | ide[i].irq=0; |
||
880 | ide[i].pdisk[IDE_MASTER]=NULL; |
||
881 | ide[i].info[IDE_MASTER].use_lba=0; |
||
882 | ide[i].pdisk[IDE_SLAVE]=NULL; |
||
883 | ide[i].info[IDE_SLAVE].use_lba=0; |
||
884 | //ide[i].reqhead=NIL; |
||
885 | //ide[i].reqtail=NIL; |
||
886 | ide[i].errors=0; |
||
887 | |||
888 | /* some check on the ide[].prd struct */ |
||
889 | addr=__lin_to_phy(ide[i].prd); |
||
890 | |||
891 | /* must be 32bits aligned! */ |
||
892 | assertk((addr&3)==0); /* this is granted by aligned(4) of the struct */ |
||
893 | |||
894 | /* must not cross 4KBytes boundaries! */ |
||
895 | if ((addr&0xfffff000)!=((addr+sizeof(ide[i].prd)-1)&0xfffff000)) { |
||
896 | printk(KERN_EMERG "ide[%i].prd cross 4Kbytes boundary!",i); |
||
897 | printk(KERN_EMERG "ide[] table is located at 0x%08lx",(long)&ide); |
||
898 | printk(KERN_EMERG "ide[%i] is located at 0x%08lx", |
||
899 | i,(long unsigned)(&ide[i])); |
||
900 | printk(KERN_EMERG "ide[%i].prd is located at 0x%08lx", |
||
901 | i,(long unsigned)(&ide[i].prd)); |
||
902 | printk(KERN_EMERG "ide[%i].prd is located at 0x%08lx (phy) for 0x%04x", |
||
903 | i,(long unsigned)addr,(int)sizeof(ide[i].prd)); |
||
904 | |||
905 | /* now! */ |
||
906 | assertk(0==-1); |
||
907 | } |
||
908 | |||
909 | } |
||
910 | |||
911 | for (i=0;i<MAXIDEMINOR;i++) { |
||
912 | |||
913 | magic_set(mtable[i].magic,IDE_MAGIC_MINOR); |
||
914 | |||
915 | mtable[i].start=0; |
||
916 | mtable[i].size=0; |
||
917 | mtable[i].used=0; |
||
918 | mtable[i].blocked=0; |
||
919 | } |
||
920 | |||
921 | ide_parm_initserver=IDEPARMS(parms).parm_initserver; |
||
922 | ide_showinfo_flag=parms->showinfo; |
||
923 | bd.bd_sectorsize=IDE_SECTOR_SIZE; |
||
924 | bd.bd_op=&ide_operations; |
||
925 | |||
926 | printk0("static data initialization... done"); |
||
927 | |||
928 | res=bdev_register(makedev(MAJOR_B_IDE,0),device_name,&bd); |
||
929 | if (res) return -1; |
||
930 | |||
931 | printk0("registering IDE to block-dev... done"); |
||
932 | |||
933 | /* Well... bus master dma operations i/o ports would be reported |
||
934 | * by the pci device management module |
||
935 | */ |
||
936 | ide_tryregister(0x1f0,0x3f0,14,3,0xe000); |
||
937 | ide_tryregister(0x170,0x370,15,-1,0xe008); |
||
938 | |||
939 | ide_scanparms(parms->config); |
||
940 | |||
941 | printk0("END"); |
||
942 | return 0; |
||
943 | } |
||
944 | |||
945 | /* |
||
946 | * |
||
947 | * |
||
948 | */ |
||
949 | |||
950 | /*++++++++++++++++++++++++++++++++++++++ |
||
951 | |||
952 | Scan for device on an IDE interface: reset the device, issue a |
||
953 | IDENTIFY command and optional a PACKET IDENTIFY; if a hard disk |
||
954 | is found it is registered to the "physical disk" module. |
||
955 | |||
956 | int ide_scan |
||
957 | return the number of device found on the interface (0,1 or 2) |
||
958 | |||
959 | int ideif |
||
960 | the interface to scan (every interface has a progess number) |
||
961 | ++++++++++++++++++++++++++++++++++++++*/ |
||
962 | |||
963 | int ide_scan(int ideif) |
||
964 | { |
||
965 | struct ata_diskid info; |
||
966 | struct atapi_diskid info2; |
||
967 | struct phdskinfo disk; |
||
968 | struct phdskinfo *phdskptr; |
||
969 | int drv; |
||
970 | int res; |
||
971 | //int ind; |
||
972 | int found; |
||
973 | int atapi; |
||
974 | int fl; |
||
975 | |||
976 | printk1("START"); |
||
977 | |||
978 | magic_assert(ide[ideif].magic,IDE_MAGIC, |
||
979 | "ide: interface(%i) overwritten",ideif); |
||
980 | |||
981 | if (ide[ideif].pdisk[IDE_MASTER]!=NULL|| |
||
982 | ide[ideif].pdisk[IDE_SLAVE]!=NULL) |
||
983 | return 0; |
||
984 | |||
985 | /* phase 0 */ |
||
986 | /* softreset */ |
||
987 | |||
988 | printk1("making a soft reset..."); |
||
989 | res=do_ide_softreset(ideif); |
||
990 | if (res) { |
||
991 | printk1("soft reset fail"); |
||
992 | #ifndef FORCE_SCANNING |
||
993 | printk1("END"); |
||
994 | return 0; |
||
995 | #endif |
||
996 | printk1("FORCE_SCANNING"); |
||
997 | } else |
||
998 | printk1("soft reset... done"); |
||
999 | |||
1000 | /* phase 1 */ |
||
1001 | /* searching for disk drive */ |
||
1002 | |||
1003 | found=0; |
||
1004 | for (drv=IDE_MASTER;drv<=(ONLY_MASTER?IDE_MASTER:IDE_SLAVE);drv++) { |
||
1005 | |||
1006 | printk1("scanning for %s",drv==IDE_MASTER?"master":"slave"); |
||
1007 | |||
1008 | atapi=0; |
||
1009 | res=ide_identify(ideif,drv,&info); |
||
1010 | |||
1011 | printk1("identify... done (device %sfound)",res==IDE_OK?"":"NOT "); |
||
1012 | |||
1013 | if (res!=IDE_OK) { |
||
1014 | atapi=1; |
||
1015 | res=ide_pidentify(ideif,drv,&info2); |
||
1016 | printk1("pidentify... done (device %sfound)",res==IDE_OK?"":"NOT "); |
||
1017 | } |
||
1018 | |||
1019 | if (res==IDE_OK) { |
||
1020 | |||
1021 | if (ide_showinfo_flag&&!found) { |
||
1022 | printk(IDELOG "ide%i: 0x%3x,%i,%i,0x%04x",ideif, |
||
1023 | ide[ideif].io_port,ide[ideif].irq, |
||
1024 | (ide[ideif].dma==255)?-1:ide[ideif].dma, |
||
1025 | ide[ideif].io_bmdma); |
||
1026 | } |
||
1027 | found++; |
||
1028 | |||
1029 | /* if this is an ATAPI device... */ |
||
1030 | if (atapi) { |
||
1031 | if (ide_showinfo_flag) { |
||
1032 | printk(IDELOG "ide%i: %s device", |
||
1033 | ideif,drv==IDE_MASTER?"master":"slave"); |
||
1034 | ide_dump_atapidiskid(&info2); |
||
1035 | } |
||
1036 | /* ATAPI devices not managed yet! */ |
||
1037 | continue; |
||
1038 | } |
||
1039 | |||
1040 | disk.pd_device=idemakedev(ideif,drv,0); |
||
1041 | |||
1042 | disk.pd_sectsize=IDE_SECTOR_SIZE; |
||
1043 | disk.pd_size=(__uint32_t)info.act_cyls*info.act_heads*info.act_sects; |
||
1044 | |||
1045 | disk.pd_logeom.cyls=disk.pd_phgeom.cyls=info.act_cyls; |
||
1046 | disk.pd_logeom.heads=disk.pd_phgeom.heads=info.act_heads; |
||
1047 | disk.pd_logeom.sectors=disk.pd_phgeom.sectors=info.act_sects; |
||
1048 | |||
1049 | if (is_LBAcapable(&info)) { |
||
1050 | ide[ideif].info[drv].use_lba=TRUE; |
||
1051 | disk.pd_ide_check_geom=0; |
||
1052 | } else { |
||
1053 | ide[ideif].info[drv].use_lba=FALSE; |
||
1054 | disk.pd_ide_check_geom=0; |
||
1055 | } |
||
1056 | |||
1057 | /* for PIO capabilities */ |
||
1058 | { |
||
1059 | __int8_t support; |
||
1060 | if (info.fields_valid&2) { |
||
1061 | if (info.eide_PIO_modes&2) support=4; |
||
1062 | else if (info.eide_PIO_modes&1) support=3; |
||
1063 | else support=info.PIO_mode; |
||
1064 | } else |
||
1065 | support=info.PIO_mode; |
||
1066 | ide[ideif].info[drv].max_pio_mode=support; |
||
1067 | } |
||
1068 | /* for DMA capabilities */ |
||
1069 | { |
||
1070 | __int8_t support; |
||
1071 | if (info.DMA_mword&4) support=2; |
||
1072 | else if (info.DMA_mword&2) support=1; |
||
1073 | else if (info.DMA_mword&1) support=0; |
||
1074 | else support=-1; |
||
1075 | ide[ideif].info[drv].max_dma_mode=support; |
||
1076 | } |
||
1077 | /* for ULTRA DMA capabilities */ |
||
1078 | { |
||
1079 | __int8_t support; |
||
1080 | if (!(info.fields_valid&4)) support=-1; |
||
1081 | else if (info.UDMA_cap&4) support=2; |
||
1082 | else if (info.UDMA_cap&2) support=1; |
||
1083 | else if (info.UDMA_cap&1) support=0; |
||
1084 | else support=-1; |
||
1085 | ide[ideif].info[drv].max_udma_mode=support; |
||
1086 | } |
||
1087 | |||
1088 | /* Well... BM-DMA used by default (if possible)*/ |
||
1089 | ide[ideif].info[drv].use_dma=0; |
||
1090 | fl=0; |
||
1091 | if (ide[ideif].info[drv].max_dma_mode!=-1) fl=1; |
||
1092 | if (ide[ideif].info[drv].max_udma_mode!=-1) fl=1; |
||
1093 | #ifdef FORCE_PIOMODE |
||
1094 | fl=0; // so use PIO mode |
||
1095 | #endif |
||
1096 | ide[ideif].info[drv].use_bm_dma=fl; |
||
1097 | |||
1098 | /* Show informations... if request */ |
||
1099 | if (ide_showinfo_flag) { |
||
1100 | printk(IDELOG "ide%i: %s device", |
||
1101 | ideif,drv==IDE_MASTER?"master":"slave"); |
||
1102 | ide_dump_diskid(&info,&ide[ideif].info[drv]); |
||
1103 | } |
||
1104 | |||
1105 | sprintf(disk.pd_name,"hd%c",'a'+ideif*2+drv); |
||
1106 | |||
1107 | /* Register physical disk information */ |
||
1108 | phdskptr=phdsk_register(&disk); |
||
1109 | if (phdskptr==NULL) continue; |
||
1110 | ide[ideif].pdisk[drv]=phdskptr; |
||
1111 | |||
1112 | /* Well, the queueing algorithm must know the physical disk layout */ |
||
1113 | ide[ideif].queue[drv].disk=phdskptr; |
||
1114 | |||
1115 | /* Activate look a head... (if possible) */ |
||
1116 | res=ide_enablelookahead(ideif,drv); |
||
1117 | if (ide_showinfo_flag) |
||
1118 | printk(IDELOG "ide%i: look ahead %s for %s device", |
||
1119 | ideif, |
||
1120 | res==IDE_OK?"activated":"not activated", |
||
1121 | drv==IDE_MASTER?"master":"slave" |
||
1122 | ); |
||
1123 | } |
||
1124 | } |
||
1125 | |||
1126 | if (found==0) { |
||
1127 | printk(IDELOG "ide: no device found on 0x%x,%i, unregistering interface", |
||
1128 | ide[ideif].io_port,ide[ideif].irq); |
||
1129 | |||
1130 | ide_unregister(ideif); |
||
1131 | |||
1132 | } |
||
1133 | |||
1134 | return found; |
||
1135 | } |
||
1136 | |||
1137 | /* --- */ |
||
1138 | |||
1139 | /*++++++++++++++++++++++++++++++++++++++ |
||
1140 | |||
1141 | This function is called by the "logical disk" module to inform this module |
||
1142 | that a logical disk partition is found [see ide_scandisk()]. |
||
1143 | |||
1144 | int _callback |
||
1145 | must return 0 to continue searching for new partition, -1 to stop |
||
1146 | scanning |
||
1147 | |||
1148 | int ind |
||
1149 | partition index (for linux users: it is the number after the device |
||
1150 | name, ex. hda1, hdb5 ) |
||
1151 | |||
1152 | struct lodskinfo *ptr |
||
1153 | information on partition found |
||
1154 | |||
1155 | void *data |
||
1156 | private data for this module: is a pointer to a __dev_t to identify |
||
1157 | the device where this partition reside |
||
1158 | ++++++++++++++++++++++++++++++++++++++*/ |
||
1159 | |||
1160 | static int _callback(int ind, struct lodskinfo *ptr, void *data) |
||
1161 | { |
||
1162 | char name[32]; |
||
1163 | int index; |
||
1164 | __dev_t dev; |
||
1165 | |||
1166 | printk2("found logical device %i",ind); |
||
1167 | |||
1168 | assertk(ind>0); |
||
1169 | if (ind>MAXIDELODSK) { |
||
1170 | printk(IDELOG "ide: found more than %i partitions... skipped!", |
||
1171 | MAXIDELODSK); |
||
1172 | return -1; |
||
1173 | } |
||
1174 | |||
1175 | index=idemindexext(*(__dev_t *)data,ind); |
||
1176 | mtable[index].start=ptr->start; |
||
1177 | mtable[index].size=ptr->size; |
||
1178 | mtable[index].used=1; |
||
1179 | |||
1180 | |||
1181 | dev=makedev(major(*(__dev_t *)data),index); |
||
1182 | sprintf(name,"hd%c%i", |
||
1183 | idehwif(dev)*2+idedriveid(dev)+'a', |
||
1184 | ind |
||
1185 | ); |
||
1186 | |||
1187 | index=bdev_register_minor(dev,name,ptr->fs_ind); |
||
1188 | |||
1189 | return 0; |
||
1190 | } |
||
1191 | |||
1192 | /*++++++++++++++++++++++++++++++++++++++ |
||
1193 | |||
1194 | Scan an IDE device to find its logical structure; it use the service |
||
1195 | from the "logical disk" module to perform this. |
||
1196 | |||
1197 | int ide_scandisk |
||
1198 | return 0 on success, other on error |
||
1199 | |||
1200 | int hwif |
||
1201 | ide interface where there is the device |
||
1202 | |||
1203 | int drv |
||
1204 | device to scan (IDE_MASTER, IDE_SLAVE) |
||
1205 | |||
1206 | ++++++++++++++++++++++++++++++++++++++*/ |
||
1207 | |||
1208 | int ide_scandisk(int hwif, int drv) |
||
1209 | { |
||
1210 | char name[8]; |
||
1211 | __dev_t device; |
||
1212 | int index; |
||
1213 | |||
1214 | printk2("START"); |
||
1215 | |||
1216 | //cprintf("hwif=%i drv=%i\n",hwif,drv); |
||
1217 | device=idemakedev(hwif,drv,0); |
||
1218 | //cprintf("device=%i\n",(int)device); |
||
1219 | index=idemindex(device); |
||
1220 | //cprintf("minor=%i\n",(int)minor(device)); |
||
1221 | //cprintf("---index=%i\n",index); |
||
1222 | |||
1223 | mtable[index].start=0; |
||
1224 | mtable[index].size=ide[hwif].pdisk[drv]->pd_size; |
||
1225 | mtable[index].used=1; |
||
1226 | sprintf(name,"hd%c",hwif*2+drv+'a'); |
||
1227 | |||
1228 | bdev_register_minor(device,name,FS_DEFAULT); |
||
1229 | |||
1230 | lodsk_scan(device, |
||
1231 | _callback, |
||
1232 | (void*)&device, |
||
1233 | ide_showinfo_flag, |
||
1234 | name); |
||
1235 | |||
1236 | printk2("END"); |
||
1237 | return 0; |
||
1238 | } |
||
1239 | |||
1240 |