root/drivers/block/hd.c

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

DEFINITIONS

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

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