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

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