Subversion Repositories shark

Rev

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