root/drivers/block/hd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. CMOS_READ
  2. read_timer
  3. hd_setup
  4. dump_status
  5. check_status
  6. controller_busy
  7. status_ok
  8. controller_ready
  9. hd_out
  10. fixstring
  11. identify_intr
  12. set_multmode_intr
  13. drive_busy
  14. reset_controller
  15. reset_hd
  16. unexpected_hd_interrupt
  17. bad_rw_intr
  18. wait_DRQ
  19. read_intr
  20. multwrite
  21. multwrite_intr
  22. write_intr
  23. recal_intr
  24. hd_times_out
  25. do_special_op
  26. hd_request
  27. do_hd_request
  28. hd_ioctl
  29. hd_open
  30. hd_release
  31. hd_interrupt
  32. hd_geninit
  33. hd_init
  34. revalidate_hddisk

   1 /*
   2  *  linux/drivers/block/hd.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * This is the low-level hd interrupt support. It traverses the
   9  * request-list, using interrupts to jump between functions. As
  10  * all the functions are called within interrupts, we may not
  11  * sleep. Special care is recommended.
  12  * 
  13  *  modified by Drew Eckhardt to check nr of hd's from the CMOS.
  14  *
  15  *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
  16  *  in the early extended-partition checks and added DM partitions
  17  *
  18  *  IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
  19  *  and general streamlining by mlord@bnr.ca (Mark Lord).
  20  */
  21 
  22 #define DEFAULT_MULT_COUNT  0   /* set to 0 to disable multiple mode at boot */
  23 #define DEFAULT_UNMASK_INTR 0   /* set to 0 to *NOT* unmask irq's more often */
  24 
  25 #include <asm/irq.h>
  26 #include <linux/errno.h>
  27 #include <linux/signal.h>
  28 #include <linux/sched.h>
  29 #include <linux/timer.h>
  30 #include <linux/fs.h>
  31 #include <linux/kernel.h>
  32 #include <linux/hdreg.h>
  33 #include <linux/genhd.h>
  34 #include <linux/malloc.h>
  35 #include <linux/string.h>
  36 
  37 #define REALLY_SLOW_IO
  38 #include <asm/system.h>
  39 #include <asm/io.h>
  40 #include <asm/segment.h>
  41 
  42 #define MAJOR_NR HD_MAJOR
  43 #include "blk.h"
  44 
  45 #define HD_IRQ 14
  46 
  47 static int revalidate_hddisk(int, int);
  48 
  49 static inline unsigned char CMOS_READ(unsigned char addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51         outb_p(addr,0x70);
  52         return inb_p(0x71);
  53 }
  54 
  55 #define HD_DELAY        0
  56 
  57 #define MAX_ERRORS     16       /* Max read/write errors/sector */
  58 #define RESET_FREQ      8       /* Reset controller every 8th retry */
  59 #define RECAL_FREQ      4       /* Recalibrate every 4th retry */
  60 #define MAX_HD          2
  61 
  62 #define STAT_OK         (READY_STAT|SEEK_STAT)
  63 #define OK_STATUS(s)    (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
  64 
  65 static void recal_intr(void);
  66 static void bad_rw_intr(void);
  67 
  68 static char recalibrate[MAX_HD] = { 0, };
  69 static char special_op[MAX_HD] = { 0, };
  70 static int access_count[MAX_HD] = {0, };
  71 static char busy[MAX_HD] = {0, };
  72 static struct wait_queue * busy_wait = NULL;
  73 
  74 static int reset = 0;
  75 static int hd_error = 0;
  76 
  77 /*
  78  *  This struct defines the HD's and their types.
  79  */
  80 struct hd_i_struct {
  81         unsigned int head,sect,cyl,wpcom,lzone,ctl;
  82         };
  83 static struct hd_driveid *hd_ident_info[MAX_HD] = {0, };
  84         
  85 #ifdef HD_TYPE
  86 static struct hd_i_struct hd_info[] = { HD_TYPE };
  87 struct hd_i_struct bios_info[] = { HD_TYPE };
  88 static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
  89 #else
  90 static struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
  91 struct hd_i_struct bios_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
  92 static int NR_HD = 0;
  93 #endif
  94 
  95 static struct hd_struct hd[MAX_HD<<6]={{0,0},};
  96 static int hd_sizes[MAX_HD<<6] = {0, };
  97 static int hd_blocksizes[MAX_HD<<6] = {0, };
  98 
  99 #if (HD_DELAY > 0)
 100 unsigned long last_req;
 101 
 102 unsigned long read_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         unsigned long t, flags;
 105         int i;
 106 
 107         save_flags(flags);
 108         cli();
 109         t = jiffies * 11932;
 110         outb_p(0, 0x43);
 111         i = inb_p(0x40);
 112         i |= inb(0x40) << 8;
 113         restore_flags(flags);
 114         return(t - i);
 115 }
 116 #endif
 117 
 118 void hd_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         int hdind = 0;
 121 
 122         if (ints[0] != 3)
 123                 return;
 124         if (bios_info[0].head != 0)
 125                 hdind=1;
 126         bios_info[hdind].head  = hd_info[hdind].head = ints[2];
 127         bios_info[hdind].sect  = hd_info[hdind].sect = ints[3];
 128         bios_info[hdind].cyl   = hd_info[hdind].cyl = ints[1];
 129         bios_info[hdind].wpcom = hd_info[hdind].wpcom = 0;
 130         bios_info[hdind].lzone = hd_info[hdind].lzone = ints[1];
 131         bios_info[hdind].ctl   = hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
 132         NR_HD = hdind+1;
 133 }
 134 
 135 static void dump_status (char *msg, unsigned int stat)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         unsigned long flags;
 138         char devc;
 139 
 140         devc = CURRENT ? 'a' + DEVICE_NR(CURRENT->dev) : '?';
 141         save_flags (flags);
 142         sti();
 143         printk("hd%c: %s: status=0x%02x { ", devc, msg, stat & 0xff);
 144         if (stat & BUSY_STAT)   printk("Busy ");
 145         if (stat & READY_STAT)  printk("DriveReady ");
 146         if (stat & WRERR_STAT)  printk("WriteFault ");
 147         if (stat & SEEK_STAT)   printk("SeekComplete ");
 148         if (stat & DRQ_STAT)    printk("DataRequest ");
 149         if (stat & ECC_STAT)    printk("CorrectedError ");
 150         if (stat & INDEX_STAT)  printk("Index ");
 151         if (stat & ERR_STAT)    printk("Error ");
 152         printk("}\n");
 153         if ((stat & ERR_STAT) == 0) {
 154                 hd_error = 0;
 155         } else {
 156                 hd_error = inb(HD_ERROR);
 157                 printk("hd%c: %s: error=0x%02x { ", devc, msg, hd_error & 0xff);
 158                 if (hd_error & BBD_ERR)         printk("BadSector ");
 159                 if (hd_error & ECC_ERR)         printk("UncorrectableError ");
 160                 if (hd_error & ID_ERR)          printk("SectorIdNotFound ");
 161                 if (hd_error & ABRT_ERR)        printk("DriveStatusError ");
 162                 if (hd_error & TRK0_ERR)        printk("TrackZeroNotFound ");
 163                 if (hd_error & MARK_ERR)        printk("AddrMarkNotFound ");
 164                 printk("}");
 165                 if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
 166                         printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
 167                                 inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
 168                         if (CURRENT)
 169                                 printk(", sector=%ld", CURRENT->sector);
 170                 }
 171                 printk("\n");
 172         }
 173         restore_flags (flags);
 174 }
 175 
 176 void check_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         int i = inb_p(HD_STATUS);
 179 
 180         if (!OK_STATUS(i)) {
 181                 dump_status("check_status", i);
 182                 bad_rw_intr();
 183         }
 184 }
 185 
 186 static int controller_busy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         int retries = 100000;
 189         unsigned char status;
 190 
 191         do {
 192                 status = inb_p(HD_STATUS);
 193         } while ((status & BUSY_STAT) && --retries);
 194         return status;
 195 }
 196 
 197 static int status_ok(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         unsigned char status = inb_p(HD_STATUS);
 200 
 201         if (status & BUSY_STAT)
 202                 return 1;       /* Ancient, but does it make sense??? */
 203         if (status & WRERR_STAT)
 204                 return 0;
 205         if (!(status & READY_STAT))
 206                 return 0;
 207         if (!(status & SEEK_STAT))
 208                 return 0;
 209         return 1;
 210 }
 211 
 212 static int controller_ready(unsigned int drive, unsigned int head)
     /* [previous][next][first][last][top][bottom][index][help] */
 213 {
 214         int retry = 100;
 215 
 216         do {
 217                 if (controller_busy() & BUSY_STAT)
 218                         return 0;
 219                 outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
 220                 if (status_ok())
 221                         return 1;
 222         } while (--retry);
 223         return 0;
 224 }
 225 
 226 static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
     /* [previous][next][first][last][top][bottom][index][help] */
 227                 unsigned int head,unsigned int cyl,unsigned int cmd,
 228                 void (*intr_addr)(void))
 229 {
 230         unsigned short port;
 231 
 232 #if (HD_DELAY > 0)
 233         while (read_timer() - last_req < HD_DELAY)
 234                 /* nothing */;
 235 #endif
 236         if (reset)
 237                 return;
 238         if (!controller_ready(drive, head)) {
 239                 reset = 1;
 240                 return;
 241         }
 242         SET_INTR(intr_addr);
 243         outb_p(hd_info[drive].ctl,HD_CMD);
 244         port=HD_DATA;
 245         outb_p(hd_info[drive].wpcom>>2,++port);
 246         outb_p(nsect,++port);
 247         outb_p(sect,++port);
 248         outb_p(cyl,++port);
 249         outb_p(cyl>>8,++port);
 250         outb_p(0xA0|(drive<<4)|head,++port);
 251         outb_p(cmd,++port);
 252 }
 253 
 254 static void hd_request (void);
 255 static unsigned int identified  [MAX_HD] = {0,}; /* 1 = drive ID already displayed   */
 256 static unsigned int unmask_intr [MAX_HD] = {0,}; /* 1 = unmask IRQs during I/O       */
 257 static unsigned int max_mult    [MAX_HD] = {0,}; /* max sectors for MultMode         */
 258 static unsigned int mult_req    [MAX_HD] = {0,}; /* requested MultMode count         */
 259 static unsigned int mult_count  [MAX_HD] = {0,}; /* currently enabled MultMode count */
 260 static struct request WCURRENT;
 261 
 262 static void fixstring (unsigned char *s, int bytecount)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264         unsigned char *p, *end = &s[bytecount &= ~1];   /* bytecount must be even */
 265 
 266         /* convert from big-endian to little-endian */
 267         for (p = end ; p != s;) {
 268                 unsigned short *pp = (unsigned short *) (p -= 2);
 269                 *pp = (*pp >> 8) | (*pp << 8);
 270         }
 271 
 272         /* strip leading blanks */
 273         while (s != end && *s == ' ')
 274                 ++s;
 275 
 276         /* compress internal blanks and strip trailing blanks */
 277         while (s != end && *s) {
 278                 if (*s++ != ' ' || (s != end && *s && *s != ' '))
 279                         *p++ = *(s-1);
 280         }
 281 
 282         /* wipe out trailing garbage */
 283         while (p != end)
 284                 *p++ = '\0';
 285 }
 286 
 287 static void identify_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 288 {
 289         unsigned int dev = DEVICE_NR(CURRENT->dev);
 290         unsigned short stat = inb_p(HD_STATUS);
 291         struct hd_driveid *id = hd_ident_info[dev];
 292 
 293         if (unmask_intr[dev])
 294                 sti();
 295         if (stat & (BUSY_STAT|ERR_STAT)) {
 296                 printk ("  hd%c: non-IDE device, %dMB, CHS=%d/%d/%d\n", dev+'a',
 297                         hd_info[dev].cyl*hd_info[dev].head*hd_info[dev].sect / 2048,
 298                         hd_info[dev].cyl, hd_info[dev].head, hd_info[dev].sect);
 299                 if (id != NULL) {
 300                         hd_ident_info[dev] = NULL;
 301                         kfree_s (id, 512);
 302                 }
 303         } else {
 304                 insw(HD_DATA, id, 256); /* get ID info */
 305                 max_mult[dev] = id->max_multsect;
 306                 if ((id->field_valid&1) && id->cur_cyls && id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
 307                         /*
 308                          * Extract the physical drive geometry for our use.
 309                          * Note that we purposely do *not* update the bios_info.
 310                          * This way, programs that use it (like fdisk) will 
 311                          * still have the same logical view as the BIOS does,
 312                          * which keeps the partition table from being screwed.
 313                          */
 314                         hd_info[dev].cyl  = id->cur_cyls;
 315                         hd_info[dev].head = id->cur_heads;
 316                         hd_info[dev].sect = id->cur_sectors; 
 317                 }
 318                 fixstring (id->serial_no, sizeof(id->serial_no));
 319                 fixstring (id->fw_rev, sizeof(id->fw_rev));
 320                 fixstring (id->model, sizeof(id->model));
 321                 printk ("  hd%c: %.40s, %dMB w/%dKB Cache, CHS=%d/%d/%d, MaxMult=%d\n",
 322                         dev+'a', id->model, id->cyls*id->heads*id->sectors/2048,
 323                         id->buf_size/2, bios_info[dev].cyl, bios_info[dev].head,
 324                         bios_info[dev].sect, id->max_multsect);
 325                 /*
 326                  * Early model Quantum drives go weird at this point,
 327                  *   but doing a recalibrate seems to "fix" them.
 328                  * (Doing a full reset confuses some other model Quantums)
 329                  */
 330                 if (!strncmp(id->model, "QUANTUM", 7))
 331                         special_op[dev] = recalibrate[dev] = 1;
 332         }
 333 #if (HD_DELAY > 0)
 334         last_req = read_timer();
 335 #endif
 336         hd_request();
 337         return;
 338 }
 339 
 340 static void set_multmode_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342         unsigned int dev = DEVICE_NR(CURRENT->dev), stat = inb_p(HD_STATUS);
 343 
 344         if (unmask_intr[dev])
 345                 sti();
 346         if (stat & (BUSY_STAT|ERR_STAT)) {
 347                 mult_req[dev] = mult_count[dev] = 0;
 348                 dump_status("set multmode failed", stat);
 349         } else {
 350                 if ((mult_count[dev] = mult_req[dev]))
 351                         printk ("  hd%c: enabled %d-sector multiple mode\n",
 352                                 dev+'a', mult_count[dev]);
 353                 else
 354                         printk ("  hd%c: disabled multiple mode\n", dev+'a');
 355         }
 356 #if (HD_DELAY > 0)
 357         last_req = read_timer();
 358 #endif
 359         hd_request();
 360         return;
 361 }
 362 
 363 static int drive_busy(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 364 {
 365         unsigned int i;
 366         unsigned char c;
 367 
 368         for (i = 0; i < 500000 ; i++) {
 369                 c = inb_p(HD_STATUS);
 370                 if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK)
 371                         return 0;
 372         }
 373         dump_status("reset timed out", c);
 374         return 1;
 375 }
 376 
 377 static void reset_controller(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 378 {
 379         int     i;
 380 
 381         outb_p(4,HD_CMD);
 382         for(i = 0; i < 1000; i++) nop();
 383         outb_p(hd_info[0].ctl & 0x0f,HD_CMD);
 384         for(i = 0; i < 1000; i++) nop();
 385         if (drive_busy())
 386                 printk("hd: controller still busy\n");
 387         else if ((hd_error = inb(HD_ERROR)) != 1)
 388                 printk("hd: controller reset failed: %02x\n",hd_error);
 389 }
 390 
 391 static void reset_hd(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 392 {
 393         static int i;
 394 
 395 repeat:
 396         if (reset) {
 397                 reset = 0;
 398                 i = -1;
 399                 reset_controller();
 400         } else {
 401                 check_status();
 402                 if (reset)
 403                         goto repeat;
 404         }
 405         if (++i < NR_HD) {
 406                 special_op[i] = recalibrate[i] = 1;
 407                 if (unmask_intr[i]) {
 408                         unmask_intr[i] = DEFAULT_UNMASK_INTR;
 409                         printk("hd%c: reset irq-unmasking to %d\n",i+'a',
 410                                 DEFAULT_UNMASK_INTR);
 411                 }
 412                 if (mult_req[i] || mult_count[i]) {
 413                         mult_count[i] = 0;
 414                         mult_req[i] = DEFAULT_MULT_COUNT;
 415                         printk("hd%c: reset multiple mode to %d\n",i+'a',
 416                                 DEFAULT_MULT_COUNT);
 417                 }
 418                 hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1,
 419                         hd_info[i].cyl,WIN_SPECIFY,&reset_hd);
 420                 if (reset)
 421                         goto repeat;
 422         } else
 423                 hd_request();
 424 }
 425 
 426 /*
 427  * Ok, don't know what to do with the unexpected interrupts: on some machines
 428  * doing a reset and a retry seems to result in an eternal loop. Right now I
 429  * ignore it, and just set the timeout.
 430  *
 431  * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
 432  * drive enters "idle", "standby", or "sleep" mode, so if the status looks
 433  * "good", we just ignore the interrupt completely.
 434  */
 435 void unexpected_hd_interrupt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 436 {
 437         unsigned int stat = inb_p(HD_STATUS);
 438 
 439         if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
 440                 dump_status ("unexpected interrupt", stat);
 441                 SET_TIMER;
 442         }
 443 }
 444 
 445 /*
 446  * bad_rw_intr() now tries to be a bit smarter and does things
 447  * according to the error returned by the controller.
 448  * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
 449  */
 450 static void bad_rw_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 451 {
 452         int dev;
 453 
 454         if (!CURRENT)
 455                 return;
 456         dev = DEVICE_NR(CURRENT->dev);
 457         if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
 458                 end_request(0);
 459                 special_op[dev] = recalibrate[dev] = 1;
 460         } else if (CURRENT->errors % RESET_FREQ == 0)
 461                 reset = 1;
 462         else if ((hd_error & TRK0_ERR) || CURRENT->errors % RECAL_FREQ == 0)
 463                 special_op[dev] = recalibrate[dev] = 1;
 464         /* Otherwise just retry */
 465 }
 466 
 467 static inline int wait_DRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 468 {
 469         int retries = 100000, stat;
 470 
 471         while (--retries > 0)
 472                 if ((stat = inb_p(HD_STATUS)) & DRQ_STAT)
 473                         return 0;
 474         dump_status("wait_DRQ", stat);
 475         return -1;
 476 }
 477 
 478 static void read_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 479 {
 480         unsigned int dev = DEVICE_NR(CURRENT->dev);
 481         int i, retries = 100000, msect = mult_count[dev], nsect;
 482 
 483         if (unmask_intr[dev])
 484                 sti();                  /* permit other IRQs during xfer */
 485         do {
 486                 i = (unsigned) inb_p(HD_STATUS);
 487                 if (i & BUSY_STAT)
 488                         continue;
 489                 if (!OK_STATUS(i))
 490                         break;
 491                 if (i & DRQ_STAT)
 492                         goto ok_to_read;
 493         } while (--retries > 0);
 494         dump_status("read_intr", i);
 495         bad_rw_intr();
 496         hd_request();
 497         return;
 498 ok_to_read:
 499         if (msect) {
 500                 if ((nsect = CURRENT->current_nr_sectors) > msect)
 501                         nsect = msect;
 502                 msect -= nsect;
 503         } else
 504                 nsect = 1;
 505         insw(HD_DATA,CURRENT->buffer,nsect<<8);
 506         CURRENT->sector += nsect;
 507         CURRENT->buffer += nsect<<9;
 508         CURRENT->errors = 0;
 509         i = (CURRENT->nr_sectors -= nsect);
 510 
 511 #ifdef DEBUG
 512         printk("hd%c: read: sectors(%ld-%ld), remaining=%ld, buffer=0x%08lx\n",
 513                 dev+'a', CURRENT->sector, CURRENT->sector+nsect,
 514                 CURRENT->nr_sectors, (unsigned long) CURRENT->buffer+(nsect<<9));
 515 #endif
 516         if ((CURRENT->current_nr_sectors -= nsect) <= 0)
 517                 end_request(1);
 518         if (i > 0) {
 519                 if (msect)
 520                         goto ok_to_read;
 521                 SET_INTR(&read_intr);
 522                 return;
 523         }
 524         (void) inb_p(HD_STATUS);
 525 #if (HD_DELAY > 0)
 526         last_req = read_timer();
 527 #endif
 528         if (CURRENT)
 529                 hd_request();
 530         return;
 531 }
 532 
 533 static inline void multwrite (unsigned int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 534 {
 535         unsigned int mcount = mult_count[dev];
 536 
 537         while (mcount--) {
 538                 outsw(HD_DATA,WCURRENT.buffer,256);
 539                 if (!--WCURRENT.nr_sectors)
 540                         return;
 541                 WCURRENT.buffer += 512;
 542                 if (!--WCURRENT.current_nr_sectors) {
 543                         WCURRENT.bh = WCURRENT.bh->b_reqnext;
 544                         if (WCURRENT.bh == NULL)
 545                                 panic("buffer list corrupted\n");
 546                         WCURRENT.current_nr_sectors = WCURRENT.bh->b_size>>9;
 547                         WCURRENT.buffer             = WCURRENT.bh->b_data;
 548                 }
 549         }
 550 }
 551 
 552 static void multwrite_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554         int i;
 555         unsigned int dev = DEVICE_NR(WCURRENT.dev);
 556 
 557         if (unmask_intr[dev])
 558                 sti();
 559         if (OK_STATUS(i=inb_p(HD_STATUS))) {
 560                 if (i & DRQ_STAT) {
 561                         if (WCURRENT.nr_sectors) {
 562                                 multwrite(dev);
 563                                 SET_INTR(&multwrite_intr);
 564                                 return;
 565                         }
 566                 } else {
 567                         if (!WCURRENT.nr_sectors) {     /* all done? */
 568                                 for (i = CURRENT->nr_sectors; i > 0;){
 569                                         i -= CURRENT->current_nr_sectors;
 570                                         end_request(1);
 571                                 }
 572 #if (HD_DELAY > 0)
 573                                 last_req = read_timer();
 574 #endif
 575                                 if (CURRENT)
 576                                         hd_request();
 577                                 return;
 578                         }
 579                 }
 580         }
 581         dump_status("multwrite_intr", i);
 582         bad_rw_intr();
 583         hd_request();
 584 }
 585 
 586 static void write_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588         int i;
 589         int retries = 100000;
 590 
 591         if (unmask_intr[DEVICE_NR(WCURRENT.dev)])
 592                 sti();
 593         do {
 594                 i = (unsigned) inb_p(HD_STATUS);
 595                 if (i & BUSY_STAT)
 596                         continue;
 597                 if (!OK_STATUS(i))
 598                         break;
 599                 if ((CURRENT->nr_sectors <= 1) || (i & DRQ_STAT))
 600                         goto ok_to_write;
 601         } while (--retries > 0);
 602         dump_status("write_intr", i);
 603         bad_rw_intr();
 604         hd_request();
 605         return;
 606 ok_to_write:
 607         CURRENT->sector++;
 608         i = --CURRENT->nr_sectors;
 609         --CURRENT->current_nr_sectors;
 610         CURRENT->buffer += 512;
 611         if (!i || (CURRENT->bh && !SUBSECTOR(i)))
 612                 end_request(1);
 613         if (i > 0) {
 614                 SET_INTR(&write_intr);
 615                 outsw(HD_DATA,CURRENT->buffer,256);
 616                 sti();
 617         } else {
 618 #if (HD_DELAY > 0)
 619                 last_req = read_timer();
 620 #endif
 621                 hd_request();
 622         }
 623         return;
 624 }
 625 
 626 static void recal_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 627 {
 628         check_status();
 629 #if (HD_DELAY > 0)
 630         last_req = read_timer();
 631 #endif
 632         hd_request();
 633 }
 634 
 635 /*
 636  * This is another of the error-routines I don't know what to do with. The
 637  * best idea seems to just set reset, and start all over again.
 638  */
 639 static void hd_times_out(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         unsigned int dev;
 642 
 643         DEVICE_INTR = NULL;
 644         if (!CURRENT)
 645                 return;
 646         disable_irq(HD_IRQ);
 647         sti();
 648         reset = 1;
 649         dev = DEVICE_NR(CURRENT->dev);
 650         printk("hd%c: timeout\n", dev+'a');
 651         if (++CURRENT->errors >= MAX_ERRORS) {
 652 #ifdef DEBUG
 653                 printk("hd%c: too many errors\n", dev+'a');
 654 #endif
 655                 end_request(0);
 656         }
 657         cli();
 658         hd_request();
 659         enable_irq(HD_IRQ);
 660 }
 661 
 662 int do_special_op (unsigned int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 663 {
 664         if (recalibrate[dev]) {
 665                 recalibrate[dev] = 0;
 666                 hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr);
 667                 return reset;
 668         }
 669         if (!identified[dev]) {
 670                 identified[dev]  = 1;
 671                 unmask_intr[dev] = DEFAULT_UNMASK_INTR;
 672                 mult_req[dev]    = DEFAULT_MULT_COUNT;
 673                 hd_out(dev,0,0,0,0,WIN_IDENTIFY,&identify_intr);
 674                 return reset;
 675         }
 676         if (mult_req[dev] != mult_count[dev]) {
 677                 hd_out(dev,mult_req[dev],0,0,0,WIN_SETMULT,&set_multmode_intr);
 678                 return reset;
 679         }
 680         if (hd_info[dev].head > 16) {
 681                 printk ("hd%c: cannot handle device with more than 16 heads - giving up\n", dev+'a');
 682                 end_request(0);
 683         }
 684         special_op[dev] = 0;
 685         return 1;
 686 }
 687 
 688 /*
 689  * The driver enables interrupts as much as possible.  In order to do this,
 690  * (a) the device-interrupt is disabled before entering hd_request(),
 691  * and (b) the timeout-interrupt is disabled before the sti().
 692  *
 693  * Interrupts are still masked (by default) whenever we are exchanging
 694  * data/cmds with a drive, because some drives seem to have very poor
 695  * tolerance for latency during I/O.  For devices which don't suffer from
 696  * that problem (most don't), the unmask_intr[] flag can be set to unmask
 697  * other interrupts during data/cmd transfers (by defining DEFAULT_UNMASK_INTR
 698  * to 1, or by using "hdparm -u1 /dev/hd?" from the shell).
 699  */
 700 static void hd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 701 {
 702         unsigned int dev, block, nsect, sec, track, head, cyl;
 703 
 704         if (CURRENT && CURRENT->dev < 0) return;
 705         if (DEVICE_INTR)
 706                 return;
 707 repeat:
 708         timer_active &= ~(1<<HD_TIMER);
 709         sti();
 710         INIT_REQUEST;
 711         if (reset) {
 712                 cli();
 713                 reset_hd();
 714                 return;
 715         }
 716         dev = MINOR(CURRENT->dev);
 717         block = CURRENT->sector;
 718         nsect = CURRENT->nr_sectors;
 719         if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
 720 #ifdef DEBUG
 721                 if (dev >= (NR_HD<<6))
 722                         printk("hd: bad minor number: device=0x%04x\n", CURRENT->dev);
 723                 else
 724                         printk("hd%c: bad access: block=%d, count=%d\n",
 725                                 (CURRENT->dev>>6)+'a', block, nsect);
 726 #endif
 727                 end_request(0);
 728                 goto repeat;
 729         }
 730         block += hd[dev].start_sect;
 731         dev >>= 6;
 732         if (special_op[dev]) {
 733                 if (do_special_op(dev))
 734                         goto repeat;
 735                 return;
 736         }
 737         sec   = block % hd_info[dev].sect + 1;
 738         track = block / hd_info[dev].sect;
 739         head  = track % hd_info[dev].head;
 740         cyl   = track / hd_info[dev].head;
 741 #ifdef DEBUG
 742         printk("hd%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx\n",
 743                 dev+'a', (CURRENT->cmd == READ)?"read":"writ",
 744                 cyl, head, sec, nsect, (unsigned long) CURRENT->buffer);
 745 #endif
 746         if (!unmask_intr[dev])
 747                 cli();
 748         if (CURRENT->cmd == READ) {
 749                 unsigned int cmd = mult_count[dev] > 1 ? WIN_MULTREAD : WIN_READ;
 750                 hd_out(dev,nsect,sec,head,cyl,cmd,&read_intr);
 751                 if (reset)
 752                         goto repeat;
 753                 return;
 754         }
 755         if (CURRENT->cmd == WRITE) {
 756                 if (mult_count[dev])
 757                         hd_out(dev,nsect,sec,head,cyl,WIN_MULTWRITE,&multwrite_intr);
 758                 else
 759                         hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
 760                 if (reset)
 761                         goto repeat;
 762                 if (wait_DRQ()) {
 763                         bad_rw_intr();
 764                         goto repeat;
 765                 }
 766                 if (mult_count[dev]) {
 767                         WCURRENT = *CURRENT;
 768                         multwrite(dev);
 769                 } else
 770                         outsw(HD_DATA,CURRENT->buffer,256);
 771                 return;
 772         }
 773         panic("unknown hd-command");
 774 }
 775 
 776 static void do_hd_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 777 {
 778         disable_irq(HD_IRQ);
 779         hd_request();
 780         enable_irq(HD_IRQ);
 781 }
 782 
 783 static int hd_ioctl(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 784         unsigned int cmd, unsigned long arg)
 785 {
 786         struct hd_geometry *loc = (struct hd_geometry *) arg;
 787         int dev, err;
 788         unsigned long flags;
 789 
 790         if ((!inode) || (!inode->i_rdev))
 791                 return -EINVAL;
 792         dev = DEVICE_NR(inode->i_rdev);
 793         if (dev >= NR_HD)
 794                 return -EINVAL;
 795         switch (cmd) {
 796                 case HDIO_GETGEO:
 797                         if (!loc)  return -EINVAL;
 798                         err = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
 799                         if (err)
 800                                 return err;
 801                         put_fs_byte(bios_info[dev].head,
 802                                 (char *) &loc->heads);
 803                         put_fs_byte(bios_info[dev].sect,
 804                                 (char *) &loc->sectors);
 805                         put_fs_word(bios_info[dev].cyl,
 806                                 (short *) &loc->cylinders);
 807                         put_fs_long(hd[MINOR(inode->i_rdev)].start_sect,
 808                                 (long *) &loc->start);
 809                         return 0;
 810                 case BLKRASET:
 811                         if(!suser())  return -EACCES;
 812                         if(arg > 0xff) return -EINVAL;
 813                         read_ahead[MAJOR(inode->i_rdev)] = arg;
 814                         return 0;
 815                 case BLKRAGET:
 816                         if (!arg)  return -EINVAL;
 817                         err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
 818                         if (err)
 819                                 return err;
 820                         put_fs_long(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
 821                         return 0;
 822                 case BLKGETSIZE:   /* Return device size */
 823                         if (!arg)  return -EINVAL;
 824                         err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
 825                         if (err)
 826                                 return err;
 827                         put_fs_long(hd[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
 828                         return 0;
 829                 case BLKFLSBUF:
 830                         if(!suser())  return -EACCES;
 831                         fsync_dev(inode->i_rdev);
 832                         invalidate_buffers(inode->i_rdev);
 833                         return 0;
 834 
 835                 case BLKRRPART: /* Re-read partition tables */
 836                         return revalidate_hddisk(inode->i_rdev, 1);
 837 
 838                 case HDIO_SET_UNMASKINTR:
 839                         if (!suser()) return -EACCES;
 840                         if ((arg > 1) || (MINOR(inode->i_rdev) & 0x3F))
 841                                 return -EINVAL;
 842                         unmask_intr[dev] = arg;
 843                         return 0;
 844 
 845                 case HDIO_GET_UNMASKINTR:
 846                         if (!arg)  return -EINVAL;
 847                         err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
 848                         if (err)
 849                                 return err;
 850                         put_fs_long(unmask_intr[dev], (long *) arg);
 851                         return 0;
 852 
 853                 case HDIO_GET_MULTCOUNT:
 854                         if (!arg)  return -EINVAL;
 855                         err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
 856                         if (err)
 857                                 return err;
 858                         put_fs_long(mult_count[dev], (long *) arg);
 859                         return 0;
 860 
 861                 case HDIO_SET_MULTCOUNT:
 862                         if (!suser()) return -EACCES;
 863                         if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
 864                         save_flags(flags);
 865                         cli();  /* a prior request might still be in progress */
 866                         if (arg > max_mult[dev])
 867                                 err = -EINVAL;  /* out of range for device */
 868                         else if (mult_req[dev] != mult_count[dev]) {
 869                                 special_op[dev] = 1;
 870                                 err = -EBUSY;   /* busy, try again */
 871                         } else {
 872                                 mult_req[dev] = arg;
 873                                 special_op[dev] = 1;
 874                                 err = 0;
 875                         }
 876                         restore_flags(flags);
 877                         return err;
 878 
 879                 case HDIO_GET_IDENTITY:
 880                         if (!arg)  return -EINVAL;
 881                         if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
 882                         if (hd_ident_info[dev] == NULL)  return -ENOMSG;
 883                         err = verify_area(VERIFY_WRITE, (char *) arg, sizeof(struct hd_driveid));
 884                         if (err)
 885                                 return err;
 886                         memcpy_tofs((char *)arg, (char *) hd_ident_info[dev], sizeof(struct hd_driveid));
 887                         return 0;
 888 
 889                 RO_IOCTLS(inode->i_rdev,arg);
 890                 default:
 891                         return -EINVAL;
 892         }
 893 }
 894 
 895 static int hd_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 896 {
 897         int target;
 898         target =  DEVICE_NR(inode->i_rdev);
 899 
 900         while (busy[target])
 901                 sleep_on(&busy_wait);
 902         access_count[target]++;
 903         return 0;
 904 }
 905 
 906 /*
 907  * Releasing a block device means we sync() it, so that it can safely
 908  * be forgotten about...
 909  */
 910 static void hd_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 911 {
 912         int target;
 913         sync_dev(inode->i_rdev);
 914 
 915         target =  DEVICE_NR(inode->i_rdev);
 916         access_count[target]--;
 917 
 918 }
 919 
 920 static void hd_geninit(void);
 921 
 922 static struct gendisk hd_gendisk = {
 923         MAJOR_NR,       /* Major number */      
 924         "hd",           /* Major name */
 925         6,              /* Bits to shift to get real from partition */
 926         1 << 6,         /* Number of partitions per real */
 927         MAX_HD,         /* maximum number of real */
 928         hd_geninit,     /* init function */
 929         hd,             /* hd struct */
 930         hd_sizes,       /* block sizes */
 931         0,              /* number */
 932         (void *) bios_info,     /* internal */
 933         NULL            /* next */
 934 };
 935         
 936 static void hd_interrupt(int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 937 {
 938         void (*handler)(void) = DEVICE_INTR;
 939 
 940         DEVICE_INTR = NULL;
 941         timer_active &= ~(1<<HD_TIMER);
 942         if (!handler)
 943                 handler = unexpected_hd_interrupt;
 944         handler();
 945         sti();
 946 }
 947 
 948 /*
 949  * This is the harddisk IRQ description. The SA_INTERRUPT in sa_flags
 950  * means we run the IRQ-handler with interrupts disabled: this is bad for
 951  * interrupt latency, but anything else has led to problems on some
 952  * machines...
 953  *
 954  * We enable interrupts in some of the routines after making sure it's
 955  * safe.
 956  */
 957 static void hd_geninit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 958 {
 959         int drive, i;
 960         extern struct drive_info drive_info;
 961         unsigned char *BIOS = (unsigned char *) &drive_info;
 962         int cmos_disks;
 963 
 964         if (!NR_HD) {      
 965                 for (drive=0 ; drive<2 ; drive++) {
 966                         bios_info[drive].cyl   = hd_info[drive].cyl = *(unsigned short *) BIOS;
 967                         bios_info[drive].head  = hd_info[drive].head = *(2+BIOS);
 968                         bios_info[drive].wpcom = hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
 969                         bios_info[drive].ctl   = hd_info[drive].ctl = *(8+BIOS);
 970                         bios_info[drive].lzone = hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
 971                         bios_info[drive].sect  = hd_info[drive].sect = *(14+BIOS);
 972 #ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
 973                         if (hd_info[drive].cyl && NR_HD == drive)
 974                                 NR_HD++;
 975 #endif
 976                         BIOS += 16;
 977                 }
 978 
 979         /*
 980                 We query CMOS about hard disks : it could be that 
 981                 we have a SCSI/ESDI/etc controller that is BIOS
 982                 compatible with ST-506, and thus showing up in our
 983                 BIOS table, but not register compatible, and therefore
 984                 not present in CMOS.
 985 
 986                 Furthermore, we will assume that our ST-506 drives
 987                 <if any> are the primary drives in the system, and 
 988                 the ones reflected as drive 1 or 2.
 989 
 990                 The first drive is stored in the high nibble of CMOS
 991                 byte 0x12, the second in the low nibble.  This will be
 992                 either a 4 bit drive type or 0xf indicating use byte 0x19 
 993                 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
 994 
 995                 Needless to say, a non-zero value means we have 
 996                 an AT controller hard disk for that drive.
 997 
 998                 
 999         */
1000 
1001                 if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
1002                         if (cmos_disks & 0x0f)
1003                                 NR_HD = 2;
1004                         else
1005                                 NR_HD = 1;
1006         }
1007         i = NR_HD;
1008         while (i-- > 0) {
1009                 /*
1010                  * The newer E-IDE BIOSs handle drives larger than 1024
1011                  * cylinders by increasing the number of logical heads
1012                  * to keep the number of logical cylinders below the
1013                  * sacred INT13 limit of 1024 (10 bits).  If that is
1014                  * what's happening here, we'll find out and correct
1015                  * it later when "identifying" the drive.
1016                  */
1017                 hd[i<<6].nr_sects = bios_info[i].head *
1018                                 bios_info[i].sect * bios_info[i].cyl;
1019                 hd_ident_info[i] = (struct hd_driveid *) kmalloc(512,GFP_KERNEL);
1020                 special_op[i] = 1;
1021         }
1022         if (NR_HD) {
1023                 if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
1024                         printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
1025                         NR_HD = 0;
1026                 }
1027         }
1028         hd_gendisk.nr_real = NR_HD;
1029 
1030         for(i=0;i<(MAX_HD << 6);i++) hd_blocksizes[i] = 1024;
1031         blksize_size[MAJOR_NR] = hd_blocksizes;
1032 }
1033 
1034 static struct file_operations hd_fops = {
1035         NULL,                   /* lseek - default */
1036         block_read,             /* read - general block-dev read */
1037         block_write,            /* write - general block-dev write */
1038         NULL,                   /* readdir - bad */
1039         NULL,                   /* select */
1040         hd_ioctl,               /* ioctl */
1041         NULL,                   /* mmap */
1042         hd_open,                /* open */
1043         hd_release,             /* release */
1044         block_fsync             /* fsync */
1045 };
1046 
1047 unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
1048 {
1049         if (register_blkdev(MAJOR_NR,"hd",&hd_fops)) {
1050                 printk("hd: unable to get major %d for harddisk\n",MAJOR_NR);
1051                 return mem_start;
1052         }
1053         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1054         read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
1055         hd_gendisk.next = gendisk_head;
1056         gendisk_head = &hd_gendisk;
1057         timer_table[HD_TIMER].fn = hd_times_out;
1058         return mem_start;
1059 }
1060 
1061 #define DEVICE_BUSY busy[target]
1062 #define USAGE access_count[target]
1063 #define CAPACITY (bios_info[target].head*bios_info[target].sect*bios_info[target].cyl)
1064 /* We assume that the the bios parameters do not change, so the disk capacity
1065    will not change */
1066 #undef MAYBE_REINIT
1067 #define GENDISK_STRUCT hd_gendisk
1068 
1069 /*
1070  * This routine is called to flush all partitions and partition tables
1071  * for a changed scsi disk, and then re-read the new partition table.
1072  * If we are revalidating a disk because of a media change, then we
1073  * enter with usage == 0.  If we are using an ioctl, we automatically have
1074  * usage == 1 (we need an open channel to use an ioctl :-), so this
1075  * is our limit.
1076  */
1077 static int revalidate_hddisk(int dev, int maxusage)
     /* [previous][next][first][last][top][bottom][index][help] */
1078 {
1079         int target, major;
1080         struct gendisk * gdev;
1081         int max_p;
1082         int start;
1083         int i;
1084         long flags;
1085 
1086         target =  DEVICE_NR(dev);
1087         gdev = &GENDISK_STRUCT;
1088 
1089         save_flags(flags);
1090         cli();
1091         if (DEVICE_BUSY || USAGE > maxusage) {
1092                 restore_flags(flags);
1093                 return -EBUSY;
1094         };
1095         DEVICE_BUSY = 1;
1096         restore_flags(flags);
1097 
1098         max_p = gdev->max_p;
1099         start = target << gdev->minor_shift;
1100         major = MAJOR_NR << 8;
1101 
1102         for (i=max_p - 1; i >=0 ; i--) {
1103                 sync_dev(major | start | i);
1104                 invalidate_inodes(major | start | i);
1105                 invalidate_buffers(major | start | i);
1106                 gdev->part[start+i].start_sect = 0;
1107                 gdev->part[start+i].nr_sects = 0;
1108         };
1109 
1110 #ifdef MAYBE_REINIT
1111         MAYBE_REINIT;
1112 #endif
1113 
1114         gdev->part[start].nr_sects = CAPACITY;
1115         resetup_one_dev(gdev, target);
1116 
1117         DEVICE_BUSY = 0;
1118         wake_up(&busy_wait);
1119         return 0;
1120 }
1121 

/* [previous][next][first][last][top][bottom][index][help] */