ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / ide / legacy / hd98.c
1 /*
2  *  Copyright (C) 1991, 1992  Linus Torvalds
3  *
4  * This is the low-level hd interrupt support. It traverses the
5  * request-list, using interrupts to jump between functions. As
6  * all the functions are called within interrupts, we may not
7  * sleep. Special care is recommended.
8  *
9  *  modified by Drew Eckhardt to check nr of hd's from the CMOS.
10  *
11  *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
12  *  in the early extended-partition checks and added DM partitions
13  *
14  *  IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
15  *  and general streamlining by Mark Lord.
16  *
17  *  Removed 99% of above. Use Mark's ide driver for those options.
18  *  This is now a lightweight ST-506 driver. (Paul Gortmaker)
19  *
20  *  Modified 1995 Russell King for ARM processor.
21  *
22  *  Bugfix: max_sectors must be <= 255 or the wheels tend to come
23  *  off in a hurry once you queue things up - Paul G. 02/2001
24  */
25
26 /* Uncomment the following if you want verbose error reports. */
27 /* #define VERBOSE_ERRORS */
28
29 #include <linux/errno.h>
30 #include <linux/signal.h>
31 #include <linux/sched.h>
32 #include <linux/timer.h>
33 #include <linux/fs.h>
34 #include <linux/kernel.h>
35 #include <linux/genhd.h>
36 #include <linux/slab.h>
37 #include <linux/string.h>
38 #include <linux/ioport.h>
39 #include <linux/mc146818rtc.h> /* CMOS defines */
40 #include <linux/init.h>
41 #include <linux/blkpg.h>
42 #include <linux/hdreg.h>
43
44 #define REALLY_SLOW_IO
45 #include <asm/system.h>
46 #include <asm/io.h>
47 #include <asm/uaccess.h>
48
49 #include "io_ports.h"
50
51 #ifdef __arm__
52 #undef  HD_IRQ
53 #endif
54 #include <asm/irq.h>
55 #ifdef __arm__
56 #define HD_IRQ IRQ_HARDDISK
57 #endif
58
59 /* Hd controller regster ports */
60
61 #define HD_DATA         0x640   /* _CTL when writing */
62 #define HD_ERROR        0x642   /* see err-bits */
63 #define HD_NSECTOR      0x644   /* nr of sectors to read/write */
64 #define HD_SECTOR       0x646   /* starting sector */
65 #define HD_LCYL         0x648   /* starting cylinder */
66 #define HD_HCYL         0x64a   /* high byte of starting cyl */
67 #define HD_CURRENT      0x64c   /* 101dhhhh , d=drive, hhhh=head */
68 #define HD_STATUS       0x64e   /* see status-bits */
69 #define HD_FEATURE      HD_ERROR        /* same io address, read=error, write=feature */
70 #define HD_PRECOMP      HD_FEATURE      /* obsolete use of this port - predates IDE */
71 #define HD_COMMAND      HD_STATUS       /* same io address, read=status, write=cmd */
72
73 #define HD_CMD          0x74c   /* used for resets */
74 #define HD_ALTSTATUS    0x74c   /* same as HD_STATUS but doesn't clear irq */
75
76 /* Bits of HD_STATUS */
77 #define ERR_STAT                0x01
78 #define INDEX_STAT              0x02
79 #define ECC_STAT                0x04    /* Corrected error */
80 #define DRQ_STAT                0x08
81 #define SEEK_STAT               0x10
82 #define SERVICE_STAT            SEEK_STAT
83 #define WRERR_STAT              0x20
84 #define READY_STAT              0x40
85 #define BUSY_STAT               0x80
86
87 /* Bits for HD_ERROR */
88 #define MARK_ERR                0x01    /* Bad address mark */
89 #define TRK0_ERR                0x02    /* couldn't find track 0 */
90 #define ABRT_ERR                0x04    /* Command aborted */
91 #define MCR_ERR                 0x08    /* media change request */
92 #define ID_ERR                  0x10    /* ID field not found */
93 #define MC_ERR                  0x20    /* media changed */
94 #define ECC_ERR                 0x40    /* Uncorrectable ECC error */
95 #define BBD_ERR                 0x80    /* pre-EIDE meaning:  block marked bad */
96 #define ICRC_ERR                0x80    /* new meaning:  CRC error during transfer */
97
98 static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
99 static struct request_queue *hd_queue;
100
101 #define CURRENT elv_next_request(hd_queue)
102
103 #define TIMEOUT_VALUE   (6*HZ)
104 #define HD_DELAY        0
105
106 #define MAX_ERRORS     16       /* Max read/write errors/sector */
107 #define RESET_FREQ      8       /* Reset controller every 8th retry */
108 #define RECAL_FREQ      4       /* Recalibrate every 4th retry */
109 #define MAX_HD          2
110
111 #define STAT_OK         (READY_STAT|SEEK_STAT)
112 #define OK_STATUS(s)    (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
113
114 static void recal_intr(void);
115 static void bad_rw_intr(void);
116
117 static int reset;
118 static int hd_error;
119
120 /*
121  *  This struct defines the HD's and their types.
122  */
123 struct hd_i_struct {
124         unsigned int head,sect,cyl,wpcom,lzone,ctl;
125         int unit;
126         int recalibrate;
127         int special_op;
128 };
129         
130 #ifdef HD_TYPE
131 static struct hd_i_struct hd_info[] = { HD_TYPE };
132 static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
133 #else
134 static struct hd_i_struct hd_info[MAX_HD];
135 static int NR_HD;
136 #endif
137
138 static struct gendisk *hd_gendisk[MAX_HD];
139
140 static struct timer_list device_timer;
141
142 #define TIMEOUT_VALUE (6*HZ)
143
144 #define SET_TIMER                                                       \
145         do {                                                            \
146                 mod_timer(&device_timer, jiffies + TIMEOUT_VALUE);      \
147         } while (0)
148
149 static void (*do_hd)(void) = NULL;
150 #define SET_HANDLER(x) \
151 if ((do_hd = (x)) != NULL) \
152         SET_TIMER; \
153 else \
154         del_timer(&device_timer);
155
156
157 #if (HD_DELAY > 0)
158 unsigned long last_req;
159
160 unsigned long read_timer(void)
161 {
162         extern spinlock_t i8253_lock;
163         unsigned long t, flags;
164         int i;
165
166         spin_lock_irqsave(&i8253_lock, flags);
167         t = jiffies * 11932;
168         outb_p(0, PIT_MODE);
169         i = inb_p(PIT_CH0);
170         i |= inb(PIT_CH0) << 8;
171         spin_unlock_irqrestore(&i8253_lock, flags);
172         return(t - i);
173 }
174 #endif
175
176 void __init hd_setup(char *str, int *ints)
177 {
178         int hdind = 0;
179
180         if (ints[0] != 3)
181                 return;
182         if (hd_info[0].head != 0)
183                 hdind=1;
184         hd_info[hdind].head = ints[2];
185         hd_info[hdind].sect = ints[3];
186         hd_info[hdind].cyl = ints[1];
187         hd_info[hdind].wpcom = 0;
188         hd_info[hdind].lzone = ints[1];
189         hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
190         NR_HD = hdind+1;
191 }
192
193 static void dump_status (const char *msg, unsigned int stat)
194 {
195         char *name = CURRENT ?
196                         CURRENT->rq_dev->bd_disk->disk_name :
197                         "hd?";
198 #ifdef VERBOSE_ERRORS
199         printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
200         if (stat & BUSY_STAT)   printk("Busy ");
201         if (stat & READY_STAT)  printk("DriveReady ");
202         if (stat & WRERR_STAT)  printk("WriteFault ");
203         if (stat & SEEK_STAT)   printk("SeekComplete ");
204         if (stat & DRQ_STAT)    printk("DataRequest ");
205         if (stat & ECC_STAT)    printk("CorrectedError ");
206         if (stat & INDEX_STAT)  printk("Index ");
207         if (stat & ERR_STAT)    printk("Error ");
208         printk("}\n");
209         if ((stat & ERR_STAT) == 0) {
210                 hd_error = 0;
211         } else {
212                 hd_error = inb(HD_ERROR);
213                 printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff);
214                 if (hd_error & BBD_ERR)         printk("BadSector ");
215                 if (hd_error & ECC_ERR)         printk("UncorrectableError ");
216                 if (hd_error & ID_ERR)          printk("SectorIdNotFound ");
217                 if (hd_error & ABRT_ERR)        printk("DriveStatusError ");
218                 if (hd_error & TRK0_ERR)        printk("TrackZeroNotFound ");
219                 if (hd_error & MARK_ERR)        printk("AddrMarkNotFound ");
220                 printk("}");
221                 if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
222                         printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
223                                 inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
224                         if (CURRENT)
225                                 printk(", sector=%ld", CURRENT->sector);
226                 }
227                 printk("\n");
228         }
229 #else
230         printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff);
231         if ((stat & ERR_STAT) == 0) {
232                 hd_error = 0;
233         } else {
234                 hd_error = inb(HD_ERROR);
235                 printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff);
236         }
237 #endif
238 }
239
240 void check_status(void)
241 {
242         int i = inb(HD_STATUS);
243
244         if (!OK_STATUS(i)) {
245                 dump_status("check_status", i);
246                 bad_rw_intr();
247         }
248 }
249
250 static int controller_busy(void)
251 {
252         int retries = 100000;
253         unsigned char status;
254
255         do {
256                 status = inb(HD_STATUS);
257         } while ((status & BUSY_STAT) && --retries);
258         return status;
259 }
260
261 static int status_ok(void)
262 {
263         unsigned char status = inb(HD_STATUS);
264
265         if (status & BUSY_STAT)
266                 return 1;       /* Ancient, but does it make sense??? */
267         if (status & WRERR_STAT)
268                 return 0;
269         if (!(status & READY_STAT))
270                 return 0;
271         if (!(status & SEEK_STAT))
272                 return 0;
273         return 1;
274 }
275
276 static int controller_ready(unsigned int drive, unsigned int head)
277 {
278         int retry = 100;
279
280         do {
281                 if (controller_busy() & BUSY_STAT)
282                         return 0;
283                 outb(0xA0 | (drive<<4) | head, HD_CURRENT);
284                 if (status_ok())
285                         return 1;
286         } while (--retry);
287         return 0;
288 }
289
290 static void hd_out(struct hd_i_struct *disk,
291                    unsigned int nsect,
292                    unsigned int sect,
293                    unsigned int head,
294                    unsigned int cyl,
295                    unsigned int cmd,
296                    void (*intr_addr)(void))
297 {
298         unsigned short port;
299
300 #if (HD_DELAY > 0)
301         while (read_timer() - last_req < HD_DELAY)
302                 /* nothing */;
303 #endif
304         if (reset)
305                 return;
306         if (!controller_ready(disk->unit, head)) {
307                 reset = 1;
308                 return;
309         }
310         SET_HANDLER(intr_addr);
311         outb(disk->ctl,HD_CMD);
312         port=HD_DATA + 2;
313         outb(disk->wpcom>>2, port); port += 2;
314         outb(nsect, port); port += 2;
315         outb(sect, port); port += 2;
316         outb(cyl, port); port += 2;
317         outb(cyl>>8, port); port += 2;
318         outb(0xA0|(disk->unit<<4)|head, port); port += 2;
319         outb(cmd, port);
320 }
321
322 static void hd_request (void);
323
324 static int drive_busy(void)
325 {
326         unsigned int i;
327         unsigned char c;
328
329         for (i = 0; i < 500000 ; i++) {
330                 c = inb(HD_STATUS);
331                 if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK)
332                         return 0;
333         }
334         dump_status("reset timed out", c);
335         return 1;
336 }
337
338 static void reset_controller(void)
339 {
340         int     i;
341
342         outb(4,HD_CMD);
343         for(i = 0; i < 1000; i++) barrier();
344         outb(hd_info[0].ctl & 0x0f,HD_CMD);
345         for(i = 0; i < 1000; i++) barrier();
346         if (drive_busy())
347                 printk("hd: controller still busy\n");
348         else if ((hd_error = inb(HD_ERROR)) != 1)
349                 printk("hd: controller reset failed: %02x\n",hd_error);
350 }
351
352 static void reset_hd(void)
353 {
354         static int i;
355
356 repeat:
357         if (reset) {
358                 reset = 0;
359                 i = -1;
360                 reset_controller();
361         } else {
362                 check_status();
363                 if (reset)
364                         goto repeat;
365         }
366         if (++i < NR_HD) {
367                 struct hd_i_struct *disk = &hd_info[i];
368                 disk->special_op = disk->recalibrate = 1;
369                 hd_out(disk, disk->sect, disk->sect, disk->head-1,
370                         disk->cyl, WIN_SPECIFY, &reset_hd);
371                 if (reset)
372                         goto repeat;
373         } else
374                 hd_request();
375 }
376
377 /*
378  * Ok, don't know what to do with the unexpected interrupts: on some machines
379  * doing a reset and a retry seems to result in an eternal loop. Right now I
380  * ignore it, and just set the timeout.
381  *
382  * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
383  * drive enters "idle", "standby", or "sleep" mode, so if the status looks
384  * "good", we just ignore the interrupt completely.
385  */
386 void unexpected_hd_interrupt(void)
387 {
388         unsigned int stat = inb(HD_STATUS);
389
390         if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
391                 dump_status ("unexpected interrupt", stat);
392                 SET_TIMER;
393         }
394 }
395
396 /*
397  * bad_rw_intr() now tries to be a bit smarter and does things
398  * according to the error returned by the controller.
399  * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
400  */
401 static void bad_rw_intr(void)
402 {
403         struct request *req = CURRENT;
404         struct hd_i_struct *disk;
405
406         if (!req)
407                 return;
408         disk = req->rq_disk->private_data;
409         if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
410                 end_request(req, 0);
411                 disk->special_op = disk->recalibrate = 1;
412         } else if (req->errors % RESET_FREQ == 0)
413                 reset = 1;
414         else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0)
415                 disk->special_op = disk->recalibrate = 1;
416         /* Otherwise just retry */
417 }
418
419 static inline int wait_DRQ(void)
420 {
421         int retries = 100000, stat;
422
423         while (--retries > 0)
424                 if ((stat = inb(HD_STATUS)) & DRQ_STAT)
425                         return 0;
426         dump_status("wait_DRQ", stat);
427         return -1;
428 }
429
430 static void read_intr(void)
431 {
432         int i, retries = 100000;
433         struct request *req;
434
435         do {
436                 i = (unsigned) inb(HD_STATUS);
437                 if (i & BUSY_STAT)
438                         continue;
439                 if (!OK_STATUS(i))
440                         break;
441                 if (i & DRQ_STAT)
442                         goto ok_to_read;
443         } while (--retries > 0);
444         dump_status("read_intr", i);
445         bad_rw_intr();
446         hd_request();
447         return;
448 ok_to_read:
449         req = CURRENT;
450         insw(HD_DATA,req->buffer,256);
451         req->sector++;
452         req->buffer += 512;
453         req->errors = 0;
454         i = --req->nr_sectors;
455         --req->current_nr_sectors;
456 #ifdef DEBUG
457         printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n",
458                 req->rq_disk->disk_name, req->sector, req->nr_sectors,
459                 req->buffer+512);
460 #endif
461         if (req->current_nr_sectors <= 0)
462                 end_request(req, 1);
463         if (i > 0) {
464                 SET_HANDLER(&read_intr);
465                 return;
466         }
467         (void) inb(HD_STATUS);
468 #if (HD_DELAY > 0)
469         last_req = read_timer();
470 #endif
471         if (CURRENT)
472                 hd_request();
473         return;
474 }
475
476 static void write_intr(void)
477 {
478         int i;
479         int retries = 100000;
480         struct request *req = CURRENT;
481
482         do {
483                 i = (unsigned) inb(HD_STATUS);
484                 if (i & BUSY_STAT)
485                         continue;
486                 if (!OK_STATUS(i))
487                         break;
488                 if ((req->nr_sectors <= 1) || (i & DRQ_STAT))
489                         goto ok_to_write;
490         } while (--retries > 0);
491         dump_status("write_intr", i);
492         bad_rw_intr();
493         hd_request();
494         return;
495 ok_to_write:
496         req->sector++;
497         i = --req->nr_sectors;
498         --req->current_nr_sectors;
499         req->buffer += 512;
500         if (!i || (req->bio && req->current_nr_sectors < 1))
501                 end_request(req, 1);
502         if (i > 0) {
503                 SET_HANDLER(&write_intr);
504                 outsw(HD_DATA,req->buffer,256);
505                 local_irq_enable();
506         } else {
507 #if (HD_DELAY > 0)
508                 last_req = read_timer();
509 #endif
510                 hd_request();
511         }
512         return;
513 }
514
515 static void recal_intr(void)
516 {
517         check_status();
518 #if (HD_DELAY > 0)
519         last_req = read_timer();
520 #endif
521         hd_request();
522 }
523
524 /*
525  * This is another of the error-routines I don't know what to do with. The
526  * best idea seems to just set reset, and start all over again.
527  */
528 static void hd_times_out(unsigned long dummy)
529 {
530         do_hd = NULL;
531
532         if (!CURRENT)
533                 return;
534
535         disable_irq(HD_IRQ);
536         local_irq_enable();
537         reset = 1;
538         printk("%s: timeout\n", CURRENT->rq_disk->disk_name);
539         if (++CURRENT->errors >= MAX_ERRORS) {
540 #ifdef DEBUG
541                 printk("%s: too many errors\n", CURRENT->rq_disk->disk_name);
542 #endif
543                 end_request(CURRENT, 0);
544         }
545         local_irq_disable();
546         hd_request();
547         enable_irq(HD_IRQ);
548 }
549
550 int do_special_op(struct hd_i_struct *disk, struct request *req)
551 {
552         if (disk->recalibrate) {
553                 disk->recalibrate = 0;
554                 hd_out(disk, disk->sect,0,0,0,WIN_RESTORE,&recal_intr);
555                 return reset;
556         }
557         if (disk->head > 16) {
558                 printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
559                 end_request(req, 0);
560         }
561         disk->special_op = 0;
562         return 1;
563 }
564
565 /*
566  * The driver enables interrupts as much as possible.  In order to do this,
567  * (a) the device-interrupt is disabled before entering hd_request(),
568  * and (b) the timeout-interrupt is disabled before the sti().
569  *
570  * Interrupts are still masked (by default) whenever we are exchanging
571  * data/cmds with a drive, because some drives seem to have very poor
572  * tolerance for latency during I/O. The IDE driver has support to unmask
573  * interrupts for non-broken hardware, so use that driver if required.
574  */
575 static void hd_request(void)
576 {
577         unsigned int block, nsect, sec, track, head, cyl;
578         struct hd_i_struct *disk;
579         struct request *req;
580
581         if (do_hd)
582                 return;
583 repeat:
584         del_timer(&device_timer);
585         local_irq_enable();
586
587         if (!CURRENT) {
588                 do_hd = NULL;
589                 return;
590         }
591         req = CURRENT;
592
593         if (reset) {
594                 local_irq_disable();
595                 reset_hd();
596                 return;
597         }
598         disk = req->rq_disk->private_data;
599         block = req->sector;
600         nsect = req->nr_sectors;
601         if (block >= get_capacity(req->rq_disk) ||
602             ((block+nsect) > get_capacity(req->rq_disk))) {
603                 printk("%s: bad access: block=%d, count=%d\n",
604                         req->rq_disk->disk_name, block, nsect);
605                 end_request(req, 0);
606                 goto repeat;
607         }
608
609         if (disk->special_op) {
610                 if (do_special_op(disk, req))
611                         goto repeat;
612                 return;
613         }
614         sec   = block % disk->sect + 1;
615         track = block / disk->sect;
616         head  = track % disk->head;
617         cyl   = track / disk->head;
618 #ifdef DEBUG
619         printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n",
620                 req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ",
621                 cyl, head, sec, nsect, req->buffer);
622 #endif
623         if (req->flags & REQ_CMD) {
624                 switch (rq_data_dir(req)) {
625                 case READ:
626                         hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr);
627                         if (reset)
628                                 goto repeat;
629                         break;
630                 case WRITE:
631                         hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
632                         if (reset)
633                                 goto repeat;
634                         if (wait_DRQ()) {
635                                 bad_rw_intr();
636                                 goto repeat;
637                         }
638                         outsw(HD_DATA,req->buffer,256);
639                         break;
640                 default:
641                         printk("unknown hd-command\n");
642                         end_request(req, 0);
643                         break;
644                 }
645         }
646 }
647
648 static void do_hd_request (request_queue_t * q)
649 {
650         disable_irq(HD_IRQ);
651         hd_request();
652         enable_irq(HD_IRQ);
653 }
654
655 static int hd_ioctl(struct inode * inode, struct file * file,
656         unsigned int cmd, unsigned long arg)
657 {
658         struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
659         struct hd_geometry *loc = (struct hd_geometry *) arg;
660         struct hd_geometry g; 
661
662         if (cmd != HDIO_GETGEO)
663                 return -EINVAL;
664         if (!loc)
665                 return -EINVAL;
666         g.heads = disk->head;
667         g.sectors = disk->sect;
668         g.cylinders = disk->cyl;
669         g.start = get_start_sect(inode->i_bdev);
670         return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
671 }
672
673 /*
674  * Releasing a block device means we sync() it, so that it can safely
675  * be forgotten about...
676  */
677
678 static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
679 {
680         void (*handler)(void) = do_hd;
681
682         do_hd = NULL;
683         del_timer(&device_timer);
684         if (!handler)
685                 handler = unexpected_hd_interrupt;
686         handler();
687         local_irq_enable();
688 }
689
690 static struct block_device_operations hd_fops = {
691         .ioctl =        hd_ioctl,
692 };
693
694 /*
695  * This is the hard disk IRQ description. The SA_INTERRUPT in sa_flags
696  * means we run the IRQ-handler with interrupts disabled:  this is bad for
697  * interrupt latency, but anything else has led to problems on some
698  * machines.
699  *
700  * We enable interrupts in some of the routines after making sure it's
701  * safe.
702  */
703
704 static int __init hd_init(void)
705 {
706         int drive;
707         if (register_blkdev(HD_MAJOR,"hd")) {
708                 printk("hd: unable to get major %d for hard disk\n",HD_MAJOR);
709                 return -1;
710         }
711         hd_queue = blk_init_queue(do_hd_request, &hd_lock);
712         if (!hd_queue) {
713                 unregister_blkdev(HD_MAJOR,"hd");
714                 return -1;
715         }
716         blk_queue_max_sectors(hd_queue, 255);
717         init_timer(&device_timer);
718         device_timer.function = hd_times_out;
719         blk_queue_hardsect_size(hd_queue, 512);
720
721 #ifdef __i386__
722         if (!NR_HD) {
723                 extern struct drive_info drive_info;
724                 unsigned char *BIOS = (unsigned char *) &drive_info;
725                 unsigned long flags;
726 #ifndef CONFIG_X86_PC9800
727                 int cmos_disks;
728 #endif
729
730                 for (drive=0 ; drive<2 ; drive++) {
731                         hd_info[drive].cyl = *(unsigned short *) BIOS;
732                         hd_info[drive].head = *(3+BIOS);
733                         hd_info[drive].sect = *(2+BIOS);
734                         hd_info[drive].wpcom = 0;
735                         hd_info[drive].ctl = *(3+BIOS) > 8 ? 8 : 0;
736                         hd_info[drive].lzone = *(unsigned short *) BIOS;
737                         if (hd_info[drive].cyl && NR_HD == drive)
738                                 NR_HD++;
739                         BIOS += 6;
740                 }
741
742         }
743 #endif /* __i386__ */
744 #ifdef __arm__
745         if (!NR_HD) {
746                 /* We don't know anything about the drive.  This means
747                  * that you *MUST* specify the drive parameters to the
748                  * kernel yourself.
749                  */
750                 printk("hd: no drives specified - use hd=cyl,head,sectors"
751                         " on kernel command line\n");
752         }
753 #endif
754         if (!NR_HD)
755                 goto out;
756
757         for (drive=0 ; drive < NR_HD ; drive++) {
758                 struct gendisk *disk = alloc_disk(64);
759                 struct hd_i_struct *p = &hd_info[drive];
760                 if (!disk)
761                         goto Enomem;
762                 disk->major = HD_MAJOR;
763                 disk->first_minor = drive << 6;
764                 disk->fops = &hd_fops;
765                 sprintf(disk->disk_name, "hd%c", 'a'+drive);
766                 disk->private_data = p;
767                 set_capacity(disk, p->head * p->sect * p->cyl);
768                 disk->queue = hd_queue;
769                 p->unit = drive;
770                 hd_gendisk[drive] = disk;
771                 printk ("%s: %luMB, CHS=%d/%d/%d\n",
772                         disk->disk_name, (unsigned long)get_capacity(disk)/2048,
773                         p->cyl, p->head, p->sect);
774         }
775
776         if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
777                 printk("hd: unable to get IRQ%d for the hard disk driver\n",
778                         HD_IRQ);
779                 goto out1;
780         }
781
782         if (!request_region(HD_DATA, 2, "hd(data)")) {
783                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
784                 NR_HD = 0;
785                 free_irq(HD_IRQ, NULL);
786                 return;
787         }
788
789         if (!request_region(HD_DATA + 2, 1, "hd"))
790         {
791                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
792                 goto out2;
793         }
794
795         if (!request_region(HD_DATA + 4, 1, "hd"))
796         {
797                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
798                 goto out3;
799         }
800
801         if (!request_region(HD_DATA + 6, 1, "hd"))
802         {
803                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
804                 goto out4;
805         }
806
807         if (!request_region(HD_DATA + 8, 1, "hd"))
808         {
809                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
810                 goto out5;
811         }
812
813         if (!request_region(HD_DATA + 10, 1, "hd"))
814         {
815                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
816                 goto out6;
817         }
818
819         if (!request_region(HD_DATA + 12, 1, "hd"))
820         {
821                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
822                 goto out7;
823         }
824
825         if (!request_region(HD_CMD, 1, "hd(cmd)"))
826         {
827                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
828                 goto out8;
829         }
830
831         if (!request_region(HD_CMD + 2, 1, "hd(cmd)"))
832         {
833                 printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
834                 goto out9;
835         }
836
837         for(drive=0; drive < NR_HD; drive++)
838                 add_disk(hd_gendisk[drive]);
839         return 0;
840
841 out9:
842         release_region(HD_CMD, 1);
843 out8:
844         release_region(HD_DATA + 12, 1);
845 out7:
846         release_region(HD_DATA + 10, 1);
847 out6:
848         release_region(HD_DATA + 8, 1);
849 out5:
850         release_region(HD_DATA + 6, 1);
851 out4:
852         release_region(HD_DATA + 4, 1);
853 out3:
854         release_region(HD_DATA + 2, 1);
855 out2:
856         release_region(HD_DATA, 2);
857         free_irq(HD_IRQ, NULL);
858 out1:
859         for (drive = 0; drive < NR_HD; drive++)
860                 put_disk(hd_gendisk[drive]);
861         NR_HD = 0;
862 out:
863         del_timer(&device_timer);
864         unregister_blkdev(HD_MAJOR,"hd");
865         blk_cleanup_queue(hd_queue);
866         return -1;
867 Enomem:
868         while (drive--)
869                 put_disk(hd_gendisk[drive]);
870         goto out;
871 }
872
873 static int parse_hd_setup (char *line) {
874         int ints[6];
875
876         (void) get_options(line, ARRAY_SIZE(ints), ints);
877         hd_setup(NULL, ints);
878
879         return 1;
880 }
881 __setup("hd=", parse_hd_setup);
882
883 module_init(hd_init);