root/kernel/blk_drv/scsi/sd.c

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

DEFINITIONS

This source file includes following definitions.
  1. sd_open
  2. sd_release
  3. sd_geninit
  4. rw_intr
  5. do_sd_request
  6. check_scsidisk_media_change
  7. sd_init_done
  8. sd_init_onedisk
  9. sd_init
  10. revalidate_scsidisk

   1 /*
   2  *      sd.c Copyright (C) 1992 Drew Eckhardt
   3  *      Linux scsi disk driver by
   4  *              Drew Eckhardt
   5  *
   6  *      <drew@colorado.edu>
   7  */
   8 
   9 #include <linux/config.h>
  10 
  11 #ifdef CONFIG_BLK_DEV_SD
  12 #include <linux/fs.h>
  13 #include <linux/kernel.h>
  14 #include <linux/sched.h>
  15 #include <linux/string.h>
  16 #include <linux/errno.h>
  17 #include <asm/system.h>
  18 
  19 #include "scsi.h"
  20 #include "hosts.h"
  21 #include "sd.h"
  22 #include "scsi_ioctl.h"
  23 
  24 #define MAJOR_NR 8
  25 
  26 #include "../blk.h"
  27 #include <linux/genhd.h>
  28 
  29 /*
  30 static const char RCSid[] = "$Header:";
  31 */
  32 
  33 #define MAX_RETRIES 5
  34 
  35 /*
  36  *      Time out in seconds
  37  */
  38 
  39 #define SD_TIMEOUT 200
  40 
  41 #define ISA_DMA_THRESHOLD (0x00ffffff)
  42 struct hd_struct sd[MAX_SD << 4];
  43 
  44 /* For a > 16 Mb system, we may need an intermediate buffer for data */
  45 
  46 struct block_buffer
  47         {
  48         unsigned long int use;
  49         unsigned char   buffer[4096];
  50         };
  51 
  52 static struct block_buffer * bb = NULL;
  53 
  54 int NR_SD=0;
  55 Scsi_Disk rscsi_disks[MAX_SD];
  56 static int sd_sizes[MAX_SD << 4] = {0, };
  57 static int this_count, total_count = 0;
  58 static int the_result;
  59 static int boot_init_done = 0;
  60 
  61 static char sense_buffer[255];
  62 int slow_scsi_io = -1;  /* This is set by aha1542.c, and others, if needed */
  63 
  64 /* used to re-read partitions. */
  65 extern void resetup_one_dev(struct gendisk *, unsigned int);
  66 
  67 extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
  68 
  69 static sd_init_onedisk(int);
  70 
  71 static int sd_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73         int target;
  74         target =  DEVICE_NR(MINOR(inode->i_rdev));
  75 
  76         if(target >= NR_SD || !rscsi_disks[target].device)
  77           return -EACCES;   /* No such device */
  78 
  79 /* Make sure that only one process can do a check_change_disk at one time.
  80  This is also used to lock out further access when the partition table is being re-read. */
  81 
  82         while (rscsi_disks[target].device->busy);
  83 
  84         if(rscsi_disks[target].device->removable) {
  85           check_disk_change(inode->i_rdev);
  86 
  87           if(!rscsi_disks[target].device->access_count)
  88             sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
  89         };
  90         rscsi_disks[target].device->access_count++;
  91         return 0;
  92 }
  93 
  94 static void sd_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         int target;
  97         sync_dev(inode->i_rdev);
  98 
  99         target =  DEVICE_NR(MINOR(inode->i_rdev));
 100 
 101         rscsi_disks[target].device->access_count--;
 102 
 103         if(rscsi_disks[target].device->removable) {
 104           if(!rscsi_disks[target].device->access_count)
 105             sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
 106         };
 107 }
 108 
 109 static struct gendisk sd_gendisk;
 110 
 111 static void sd_geninit (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 112         int i;
 113         for (i = 0; i < NR_SD; ++i)
 114           sd[i << 4].nr_sects = rscsi_disks[i].capacity;
 115         sd_gendisk.nr_real = NR_SD;
 116 }
 117 
 118 
 119 static struct file_operations sd_fops = {
 120         NULL,                   /* lseek - default */
 121         block_read,             /* read - general block-dev read */
 122         block_write,            /* write - general block-dev write */
 123         NULL,                   /* readdir - bad */
 124         NULL,                   /* select */
 125         sd_ioctl,               /* ioctl */
 126         NULL,                   /* mmap */
 127         sd_open,                /* open code */
 128         sd_release              /* release */
 129 };
 130 
 131 static struct gendisk sd_gendisk = {
 132         MAJOR_NR,               /* Major number */
 133         "sd",           /* Major name */
 134         4,              /* Bits to shift to get real from partition */
 135         1 << 4,         /* Number of partitions per real */
 136         MAX_SD,         /* maximum number of real */
 137         sd_geninit,     /* init function */
 138         sd,             /* hd struct */
 139         sd_sizes,       /* block sizes */
 140         0,              /* number */
 141         (void *) rscsi_disks,   /* internal */
 142         NULL            /* next */
 143 };
 144 
 145 /*
 146         rw_intr is the interrupt routine for the device driver.  It will
 147         be notified on the end of a SCSI read / write, and
 148         will take on of several actions based on success or failure.
 149 */
 150 
 151 static void rw_intr (int host, int result)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153         if (HOST != host)
 154                 panic ("sd.o : rw_intr() recieving interrupt for different host.");
 155 
 156 #ifdef DEBUG
 157         printk("sd%d : rw_intr(%d, %x)\n", MINOR(CURRENT->dev), host, result);
 158 #endif
 159 
 160 /*
 161         First case : we assume that the command succeeded.  One of two things will
 162         happen here.  Either we will be finished, or there will be more
 163         sectors that we were unable to read last time.
 164 */
 165 
 166         if (!result) {
 167           if (bb && bb[DEVICE_NR(CURRENT->dev)].use && CURRENT->cmd == READ)
 168             {
 169               memcpy((char *)CURRENT->buffer, 
 170                      bb[DEVICE_NR(CURRENT->dev)].buffer,
 171                      this_count << 9);
 172 #ifdef DEBUG
 173               printk("R");
 174 #endif
 175             };
 176           if(bb) bb[DEVICE_NR(CURRENT->dev)].use = 0;
 177 
 178                 CURRENT->nr_sectors -= this_count;
 179                 if (slow_scsi_io == host) {
 180                   total_count -= this_count;
 181                   if(total_count){
 182                     CURRENT->sector += this_count;
 183                     CURRENT->buffer += (this_count << 9);
 184                     do_sd_request();
 185                     return;
 186                   };
 187                 };
 188 
 189 #ifdef DEBUG
 190                 printk("sd%d : %d sectors remain.\n", MINOR(CURRENT->dev), CURRENT->nr_sectors);
 191 #endif
 192 
 193 /*
 194  *      If multiple sectors are requested in one buffer, then
 195  *      they will have been finished off by the first command.  If
 196  *      not, then we have a multi-buffer command.
 197  */
 198                 if (CURRENT->nr_sectors)
 199                         {
 200                         CURRENT->sector += this_count;
 201                         CURRENT->errors = 0;
 202 
 203                         if (!CURRENT->bh)
 204                                 {
 205 #ifdef DEBUG
 206                                 printk("sd%d : handling page request, no buffer\n",
 207                                         MINOR(CURRENT->dev));
 208 #endif
 209 
 210 /*
 211         The CURRENT->nr_sectors field is always done in 512 byte sectors,
 212         even if this really isn't the case.
 213 */
 214                                 (char *) CURRENT->buffer += this_count << 9;
 215                                 }
 216                         else
 217                                 {
 218 #ifdef DEBUG
 219                                 printk("sd%d :  handling linked buffer request\n", MINOR(CURRENT->dev));
 220 #endif
 221                                 end_request(1);
 222                                 }
 223                         }
 224                 else
 225                         end_request(1);
 226                 do_sd_request();
 227         }
 228 
 229 /*
 230  *      Of course, the error handling code is a little Fubar down in scsi.c.
 231  *      Version 2 of the drivers will fix that, and we will *really* recover
 232  *      from errors.
 233  */
 234 
 235 /*
 236         Now, if we were good little boys and girls, Santa left us a request
 237         sense buffer.  We can extract information from this, so we
 238         can choose a block to remap, etc.
 239 */
 240 
 241         else if (driver_byte(result) & DRIVER_SENSE) {
 242           if (bb) bb[DEVICE_NR(CURRENT->dev)].use = 0;
 243                 if (sugestion(result) == SUGGEST_REMAP) {
 244 #ifdef REMAP
 245 /*
 246         Not yet implemented.  A read will fail after being remapped,
 247         a write will call the strategy routine again.
 248 */
 249                         if rscsi_disks[DEVICE_NR(CURRENT->dev)].remap
 250                                 {
 251                                 result = 0;
 252                                 }
 253                         else
 254 
 255 #endif
 256                 }
 257 
 258 /* A unit attention comes up if there is a media change on a removable
 259    disk drive */
 260 
 261                 else if ((sense_buffer[0] & 0x7f) == 0x70) {
 262                         if ((sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
 263                                 /* detected disc change.  set a bit and quietly refuse  */
 264                                 /* further access.                                      */
 265 
 266                                 rscsi_disks[DEVICE_NR(CURRENT->dev)].device->changed = 1;
 267                                 end_request(0);
 268                                 do_sd_request();
 269                                 return;
 270                         }
 271                       }
 272 
 273 /*
 274         If we had an ILLEGAL REQUEST returned, then we may have performed
 275         an unsupported command.  The only thing this should be would be a  ten
 276         byte read where only a six byte read was supportted.  Also, on a
 277         system where READ CAPACITY failed, we mave have read past the end of the
 278         disk.
 279 */
 280                 else if (sense_buffer[7] == ILLEGAL_REQUEST) {
 281                         if (rscsi_disks[DEVICE_NR(CURRENT->dev)].ten) {
 282                                 rscsi_disks[DEVICE_NR(CURRENT->dev)].ten = 0;
 283                                 do_sd_request();
 284                                 result = 0;
 285                         } else {
 286                         }
 287                 }
 288         }
 289         if (result) {
 290                 if (bb) bb[DEVICE_NR(CURRENT->dev)].use = 0;
 291                 printk("SCSI disk error : host %d id %d lun %d return code = %x\n",
 292                        rscsi_disks[DEVICE_NR(CURRENT->dev)].device->host_no,
 293                        rscsi_disks[DEVICE_NR(CURRENT->dev)].device->id,
 294                        rscsi_disks[DEVICE_NR(CURRENT->dev)].device->lun, result);
 295 
 296                 if (driver_byte(result) & DRIVER_SENSE)
 297                         printk("\tSense class %x, sense error %x, extended sense %x\n",
 298                                 sense_class(sense_buffer[0]),
 299                                 sense_error(sense_buffer[0]),
 300                                 sense_buffer[2] & 0xf);
 301 
 302                 end_request(0);
 303                 do_sd_request();
 304         }
 305 }
 306 
 307 /*
 308         do_sd_request() is the request handler function for the sd driver.
 309         Its function in life is to take block device requests, and translate
 310         them to SCSI commands.
 311 */
 312 
 313 static void do_sd_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 314 {
 315         int dev, block;
 316         unsigned char cmd[10];
 317         char * buff;
 318 
 319 repeat:
 320         INIT_REQUEST;
 321         dev =  MINOR(CURRENT->dev);
 322         block = CURRENT->sector;
 323 
 324 #ifdef DEBUG
 325         printk("Doing sd request, dev = %d, block = %d\n", dev, block);
 326 #endif
 327 
 328         if (dev >= (NR_SD << 4) || block + CURRENT->nr_sectors > sd[dev].nr_sects)
 329                 {
 330                 end_request(0);
 331                 goto repeat;
 332                 }
 333 
 334         block += sd[dev].start_sect;
 335         dev = DEVICE_NR(dev);
 336 
 337         if (rscsi_disks[dev].device->changed)
 338                 {
 339 /*
 340  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 341  */
 342                 /* printk("SCSI disk has been changed.  Prohibiting further I/O.\n");   */
 343                 end_request(0);
 344                 goto repeat;
 345                 }
 346 
 347 #ifdef DEBUG
 348         printk("sd%d : real dev = /dev/sd%d, block = %d\n", MINOR(CURRENT->dev), dev, block);
 349 #endif
 350 
 351 
 352         if (!CURRENT->bh)
 353                 this_count = CURRENT->nr_sectors;
 354         else
 355                 this_count = (BLOCK_SIZE / 512);
 356 
 357 
 358 /* This is a temporary hack for the AHA1742. */
 359         if(slow_scsi_io == HOST) {
 360           if(total_count == 0)
 361             total_count = this_count;
 362           this_count = 1;  /* Take only 512 bytes at a time */
 363         };
 364 
 365 #ifdef DEBUG
 366         printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev),
 367                 (CURRENT->cmd == WRITE) ? "writing" : "reading",
 368                 this_count, CURRENT->nr_sectors);
 369 #endif
 370 
 371         switch (CURRENT->cmd)
 372                 {
 373                 case WRITE :
 374                         if (!rscsi_disks[dev].device->writeable)
 375                                 {
 376                                 end_request(0);
 377                                 goto repeat;
 378                                 }
 379                         cmd[0] = WRITE_6;
 380                         break;
 381                 case READ :
 382                         cmd[0] = READ_6;
 383                         break;
 384                 default :
 385                         printk ("Unknown sd command %d\r\n", CURRENT->cmd);
 386                         panic("");
 387                 }
 388 
 389         cmd[1] = (LUN << 5) & 0xe0;
 390 
 391         buff = CURRENT->buffer;
 392 
 393 /* Curses, curses. If this is a DMA transfer, we could be screwed. */
 394         if (((int) buff) + (this_count << 9) > ISA_DMA_THRESHOLD && 
 395             (scsi_hosts[HOST].unchecked_isa_dma)) {
 396           if (bb[DEVICE_NR(CURRENT->dev)].use) panic ("block buffer already in use");
 397           bb[DEVICE_NR(CURRENT->dev)].use = 1;
 398           if(this_count > 8) this_count = 8;
 399           if (CURRENT->cmd == WRITE) {
 400             memcpy(bb[DEVICE_NR(CURRENT->dev)].buffer,
 401                    (char *)CURRENT->buffer, this_count << 9);
 402 #ifdef DEBUG
 403             printk("W");
 404 #endif
 405           };
 406           buff = bb[DEVICE_NR(CURRENT->dev)].buffer;
 407         };
 408 
 409         if (((this_count > 0xff) ||  (block > 0x1fffff)) && rscsi_disks[dev].ten)
 410                 {
 411                 if (this_count > 0xffff)
 412                         this_count = 0xffff;
 413 
 414                 cmd[0] += READ_10 - READ_6 ;
 415                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 416                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 417                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 418                 cmd[5] = (unsigned char) block & 0xff;
 419                 cmd[6] = cmd[9] = 0;
 420                 cmd[7] = (unsigned char) (this_count >> 8) & 0xff;
 421                 cmd[8] = (unsigned char) this_count & 0xff;
 422                 }
 423         else
 424                 {
 425                 if (this_count > 0xff)
 426                         this_count = 0xff;
 427 
 428                 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 429                 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 430                 cmd[3] = (unsigned char) block & 0xff;
 431                 cmd[4] = (unsigned char) this_count;
 432                 cmd[5] = 0;
 433                 }
 434 
 435         scsi_do_cmd (HOST, ID, (void *) cmd, buff, this_count << 9,
 436                      rw_intr, SD_TIMEOUT, sense_buffer, MAX_RETRIES);
 437 }
 438 
 439 int check_scsidisk_media_change(int full_dev, int flag){
     /* [previous][next][first][last][top][bottom][index][help] */
 440         int retval;
 441         int target;
 442         struct inode inode;
 443 
 444         target =  DEVICE_NR(MINOR(full_dev));
 445 
 446         if (target >= NR_SD) {
 447                 printk("SCSI disk request error: invalid device.\n");
 448                 return 0;
 449         };
 450 
 451         if(!rscsi_disks[target].device->removable) return 0;
 452 
 453         inode.i_rdev = full_dev;  /* This is all we really need here */
 454         retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
 455 
 456         if(retval){ /* Unable to test, unit probably not ready.  This usually
 457                      means there is no disc in the drive.  Mark as changed,
 458                      and we will figure it out later once the drive is
 459                      available again.  */
 460 
 461           rscsi_disks[target].device->changed = 1;
 462           return 1; /* This will force a flush, if called from
 463                        check_disk_change */
 464         };
 465 
 466         retval = rscsi_disks[target].device->changed;
 467         if(!flag) rscsi_disks[target].device->changed = 0;
 468         return retval;
 469 }
 470 
 471 static void sd_init_done (int host, int result)
     /* [previous][next][first][last][top][bottom][index][help] */
 472 {
 473         the_result = result;
 474 }
 475 
 476 
 477 static int sd_init_onedisk(int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 478 {
 479   int j = 0;
 480   unsigned char cmd[10];
 481   unsigned char buffer[513];
 482   int try_again;
 483 
 484   try_again=2;
 485   cmd[0] = READ_CAPACITY;
 486   cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
 487   memset ((void *) &cmd[2], 0, 8);
 488 
 489   /*
 490    *    Super Kludge - since the midlevel error handling code doesn't work
 491    *    Version 2 will - it's under development 8^)
 492    *
 493    *    We manually retry
 494    */
 495 
 496   do {
 497     the_result = -1;
 498 #ifdef DEBUG
 499     printk("sd%d : READ CAPACITY\n ", i);
 500 #endif
 501     scsi_do_cmd (rscsi_disks[i].device->host_no ,
 502                  rscsi_disks[i].device->id,
 503                  (void *) cmd, (void *) buffer,
 504                  512, sd_init_done,  SD_TIMEOUT, sense_buffer,
 505                  MAX_RETRIES);
 506 
 507     while(the_result < 0);
 508   } while (try_again  && the_result);
 509   /*
 510    *    The SCSI standard says "READ CAPACITY is necessary for self confuring software"
 511    *    While not mandatory, support of READ CAPACITY is strongly encouraged.
 512    *    We used to die if we couldn't successfully do a READ CAPACITY.
 513    *    But, now we go on about our way.  The side effects of this are
 514    *
 515    *    1.  We can't know block size with certainty.  I have said "512 bytes is it"
 516    *            as this is most common.
 517    *
 518    *    2.  Recovery from when some one attempts to read past the end of the raw device will
 519    *        be slower.
 520    */
 521 
 522   if (the_result)
 523     {
 524       printk ("sd%d : READ CAPACITY failed.\n"
 525               "sd%d : status = %x, message = %02x, host = %02x, driver = %02x \n",
 526               i,i,
 527               rscsi_disks[i].device->host_no, rscsi_disks[i].device->id,
 528               rscsi_disks[i].device->lun,
 529               status_byte(the_result),
 530               msg_byte(the_result),
 531               host_byte(the_result),
 532               driver_byte(the_result)
 533               );
 534       if (driver_byte(the_result)  & DRIVER_SENSE)
 535         printk("sd%d : extended sense code = %1x \n", i, sense_buffer[2] & 0xf);
 536       else
 537         printk("sd%d : sense not available. \n", i);
 538 
 539       printk("sd%d : block size assumed to be 512 bytes, disk size 1GB.  \n", i);
 540       rscsi_disks[i].capacity = 0x1fffff;
 541       rscsi_disks[i].sector_size = 512;
 542     }
 543   else
 544     {
 545       rscsi_disks[i].capacity = (buffer[0] << 24) |
 546         (buffer[1] << 16) |
 547           (buffer[2] << 8) |
 548             buffer[3];
 549 
 550       if ((rscsi_disks[i].sector_size = (buffer[4] << 24) |
 551            (buffer[5] << 16) |
 552            (buffer[6] << 8) |
 553            buffer[7]) != 512)
 554         {
 555           printk ("sd%d : unsupported sector size %d.\n",
 556                   i, rscsi_disks[i].sector_size);
 557           if(rscsi_disks[j].device->removable){
 558             rscsi_disks[j].capacity = 0;
 559           } else {
 560             printk ("scsi : deleting disk entry.\n");
 561             for  (j=i;  j < NR_SD;)
 562               rscsi_disks[j] = rscsi_disks[++j];
 563             --i;
 564             return i;
 565           };
 566         }
 567     }
 568 
 569   rscsi_disks[i].ten = 1;
 570   rscsi_disks[i].remap = 1;
 571   return i;
 572 }
 573 
 574 /*
 575         The sd_init() function looks at all SCSI drives present, determines
 576         their size, and reads partition table entries for them.
 577 */
 578 
 579 unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 580 {
 581         int i;
 582 
 583         for (i = 0; i < NR_SD; ++i)
 584           i = sd_init_onedisk(i);
 585 
 586         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 587         blkdev_fops[MAJOR_NR] = &sd_fops;
 588         sd_gendisk.next = gendisk_head;
 589         gendisk_head = &sd_gendisk;
 590         boot_init_done++;
 591 /* Allocate DMA block buffer */
 592         if(memory_end > ISA_DMA_THRESHOLD) {
 593           bb = (struct block_buffer *) memory_start;
 594           memory_start += NR_SD * sizeof(struct block_buffer);
 595           for (i=0; i < NR_SD; ++i) bb[i].use = 0;
 596         };
 597         return memory_start;
 598 }
 599 
 600 #define DEVICE_BUSY rscsi_disks[target].device->busy
 601 #define USAGE rscsi_disks[target].device->access_count
 602 #define CAPACITY rscsi_disks[target].capacity
 603 #define MAYBE_REINIT  sd_init_onedisk(target)
 604 #define GENDISK_STRUCT sd_gendisk
 605 
 606 /* This routine is called to flush all partitions and partition tables
 607    for a changed scsi disk, and then re-read the new partition table.
 608    If we are revalidating a disk because of a media change, then we
 609    enter with usage == 0.  If we are using an ioctl, we automatically have
 610    usage == 1 (we need an open channel to use an ioctl :-), so this
 611    is our limit.
 612  */
 613 int revalidate_scsidisk(int dev, int maxusage){
     /* [previous][next][first][last][top][bottom][index][help] */
 614           int target, major;
 615           struct gendisk * gdev;
 616           int max_p;
 617           int start;
 618           int i;
 619 
 620           target =  DEVICE_NR(MINOR(dev));
 621           gdev = &GENDISK_STRUCT;
 622 
 623           sti();
 624           if (DEVICE_BUSY || USAGE > maxusage) {
 625             cli();
 626             printk("Device busy for revalidation (usage=%d)\n", USAGE);
 627             return -EBUSY;
 628           };
 629           DEVICE_BUSY = 1;
 630           cli();
 631 
 632           max_p = gdev->max_p;
 633           start = target << gdev->minor_shift;
 634           major = MAJOR_NR << 8;
 635 
 636           for (i=max_p - 1; i >=0 ; i--) {
 637             sync_dev(major | start | i);
 638             invalidate_inodes(major | start | i);
 639             invalidate_buffers(major | start | i);
 640             gdev->part[i].start_sect = 0;
 641             gdev->part[i].nr_sects = 0;
 642           };
 643 
 644 #ifdef MAYBE_REINIT
 645           MAYBE_REINIT;
 646 #endif
 647 
 648           gdev->part[start].nr_sects = CAPACITY;
 649           resetup_one_dev(gdev, target);
 650 
 651           DEVICE_BUSY = 0;
 652           return 0;
 653 }
 654 #endif
 655 
 656 
 657 

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