root/drivers/scsi/sr.c

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

DEFINITIONS

This source file includes following definitions.
  1. sr_release
  2. check_cdrom_media_change
  3. rw_intr
  4. sr_photocd
  5. sr_open
  6. do_sr_request
  7. requeue_sr_request
  8. sr_detect
  9. sr_attach
  10. sr_init_done
  11. get_sectorsize
  12. sr_init
  13. sr_finish
  14. sr_detach

   1 /*
   2  *      sr.c Copyright (C) 1992 David Giller
   3  *           Copyright (C) 1993, 1994, 1995 Eric Youngdale
   4  *
   5  *      adapted from:
   6  *      sd.c Copyright (C) 1992 Drew Eckhardt 
   7  *      Linux scsi disk driver by
   8  *              Drew Eckhardt 
   9  *
  10  *      <drew@colorado.edu>
  11  *
  12  *       Modified by Eric Youngdale ericy@cais.com to
  13  *       add scatter-gather, multiple outstanding request, and other
  14  *       enhancements.
  15  *
  16  *       Modified by Eric Youngdale eric@aib.com to support loadable
  17  *       low-level scsi drivers.
  18  */
  19 
  20 #include <linux/fs.h>
  21 #include <linux/kernel.h>
  22 #include <linux/sched.h>
  23 #include <linux/string.h>
  24 #include <linux/errno.h>
  25 #include <linux/cdrom.h>
  26 #include <asm/system.h>
  27 
  28 #define MAJOR_NR SCSI_CDROM_MAJOR
  29 #include "../block/blk.h"
  30 #include "scsi.h"
  31 #include "hosts.h"
  32 #include "sr.h"
  33 #include "scsi_ioctl.h"   /* For the door lock/unlock commands */
  34 #include "constants.h"
  35 
  36 #define MAX_RETRIES 3
  37 #define SR_TIMEOUT 15000
  38 
  39 static void sr_init(void);
  40 static void sr_finish(void);
  41 static int sr_attach(Scsi_Device *);
  42 static int sr_detect(Scsi_Device *);
  43 static void sr_detach(Scsi_Device *);
  44 
  45 struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", TYPE_ROM, 
  46                                              SCSI_CDROM_MAJOR, 0, 0, 0, 1,
  47                                              sr_detect, sr_init,
  48                                              sr_finish, sr_attach, sr_detach};
  49 
  50 Scsi_CD * scsi_CDs;
  51 static int * sr_sizes;
  52 
  53 static int * sr_blocksizes;
  54 
  55 static int sr_open(struct inode *, struct file *);
  56 static void get_sectorsize(int);
  57 
  58 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  59 
  60 void requeue_sr_request (Scsi_Cmnd * SCpnt);
  61 static int check_cdrom_media_change(dev_t);
  62 
  63 static void sr_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65         sync_dev(inode->i_rdev);
  66         if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
  67           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
  68         if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
  69           (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)--;
  70 }
  71 
  72 static struct file_operations sr_fops = 
  73 {
  74         NULL,                   /* lseek - default */
  75         block_read,             /* read - general block-dev read */
  76         block_write,            /* write - general block-dev write */
  77         NULL,                   /* readdir - bad */
  78         NULL,                   /* select */
  79         sr_ioctl,               /* ioctl */
  80         NULL,                   /* mmap */
  81         sr_open,                /* special open code */
  82         sr_release,             /* release */
  83         NULL,                   /* fsync */
  84         NULL,                   /* fasync */
  85         check_cdrom_media_change,  /* Disk change */
  86         NULL                    /* revalidate */
  87 };
  88 
  89 /*
  90  * This function checks to see if the media has been changed in the
  91  * CDROM drive.  It is possible that we have already sensed a change,
  92  * or the drive may have sensed one and not yet reported it.  We must
  93  * be ready for either case. This function always reports the current
  94  * value of the changed bit.  If flag is 0, then the changed bit is reset.
  95  * This function could be done as an ioctl, but we would need to have
  96  * an inode for that to work, and we do not always have one.
  97  */
  98 
  99 int check_cdrom_media_change(dev_t full_dev){
     /* [previous][next][first][last][top][bottom][index][help] */
 100         int retval, target;
 101         struct inode inode;
 102         int flag = 0;
 103 
 104         target =  MINOR(full_dev);
 105 
 106         if (target >= sr_template.nr_dev) {
 107                 printk("CD-ROM request error: invalid device.\n");
 108                 return 0;
 109         };
 110 
 111         inode.i_rdev = full_dev;  /* This is all we really need here */
 112         retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
 113 
 114         if(retval){ /* Unable to test, unit probably not ready.  This usually
 115                      means there is no disc in the drive.  Mark as changed,
 116                      and we will figure it out later once the drive is
 117                      available again.  */
 118 
 119           scsi_CDs[target].device->changed = 1;
 120           return 1; /* This will force a flush, if called from
 121                        check_disk_change */
 122         };
 123 
 124         retval = scsi_CDs[target].device->changed;
 125         if(!flag) {
 126           scsi_CDs[target].device->changed = 0;
 127           /* If the disk changed, the capacity will now be different,
 128              so we force a re-read of this information */
 129           if (retval) scsi_CDs[target].needs_sector_size = 1;
 130         };
 131         return retval;
 132 }
 133 
 134 /*
 135  * rw_intr is the interrupt routine for the device driver.  It will be notified on the 
 136  * end of a SCSI read / write, and will take on of several actions based on success or failure.
 137  */
 138 
 139 static void rw_intr (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         int result = SCpnt->result;
 142         int this_count = SCpnt->this_count;
 143 
 144 #ifdef DEBUG
 145         printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
 146 #endif
 147         if (!result)
 148                 { /* No error */
 149                   if (SCpnt->use_sg == 0) {
 150                     if (SCpnt->buffer != SCpnt->request.buffer)
 151                       {
 152                         int offset;
 153                         offset = (SCpnt->request.sector % 4) << 9;
 154                         memcpy((char *)SCpnt->request.buffer, 
 155                                (char *)SCpnt->buffer + offset, 
 156                                this_count << 9);
 157                         /* Even though we are not using scatter-gather, we look
 158                            ahead and see if there is a linked request for the
 159                            other half of this buffer.  If there is, then satisfy
 160                            it. */
 161                         if((offset == 0) && this_count == 2 &&
 162                            SCpnt->request.nr_sectors > this_count && 
 163                            SCpnt->request.bh &&
 164                            SCpnt->request.bh->b_reqnext &&
 165                            SCpnt->request.bh->b_reqnext->b_size == 1024) {
 166                           memcpy((char *)SCpnt->request.bh->b_reqnext->b_data, 
 167                                  (char *)SCpnt->buffer + 1024, 
 168                                  1024);
 169                           this_count += 2;
 170                         };
 171                         
 172                         scsi_free(SCpnt->buffer, 2048);
 173                       }
 174                   } else {
 175                     struct scatterlist * sgpnt;
 176                     int i;
 177                     sgpnt = (struct scatterlist *) SCpnt->buffer;
 178                     for(i=0; i<SCpnt->use_sg; i++) {
 179                       if (sgpnt[i].alt_address) {
 180                         if (sgpnt[i].alt_address != sgpnt[i].address) {
 181                           memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
 182                         };
 183                         scsi_free(sgpnt[i].address, sgpnt[i].length);
 184                       };
 185                     };
 186                     scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 187                     if(SCpnt->request.sector % 4) this_count -= 2;
 188 /* See   if there is a padding record at the end that needs to be removed */
 189                     if(this_count > SCpnt->request.nr_sectors)
 190                       this_count -= 2;
 191                   };
 192 
 193 #ifdef DEBUG
 194                 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors, 
 195                        this_count);
 196 #endif
 197                 if (SCpnt->request.nr_sectors > this_count)
 198                         {        
 199                         SCpnt->request.errors = 0;
 200                         if (!SCpnt->request.bh)
 201                             panic("sr.c: linked page request (%lx %x)",
 202                                   SCpnt->request.sector, this_count);
 203                         }
 204 
 205                   SCpnt = end_scsi_request(SCpnt, 1, this_count);  /* All done */
 206                   requeue_sr_request(SCpnt);
 207                   return;
 208                 } /* Normal completion */
 209 
 210         /* We only come through here if we have an error of some kind */
 211 
 212 /* Free up any indirection buffers we allocated for DMA purposes. */
 213         if (SCpnt->use_sg) {
 214           struct scatterlist * sgpnt;
 215           int i;
 216           sgpnt = (struct scatterlist *) SCpnt->buffer;
 217           for(i=0; i<SCpnt->use_sg; i++) {
 218             if (sgpnt[i].alt_address) {
 219               scsi_free(sgpnt[i].address, sgpnt[i].length);
 220             };
 221           };
 222           scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 223         } else {
 224           if (SCpnt->buffer != SCpnt->request.buffer)
 225             scsi_free(SCpnt->buffer, SCpnt->bufflen);
 226         };
 227 
 228         if (driver_byte(result) != 0) {
 229                 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
 230                         if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
 231                                 /* detected disc change.  set a bit and quietly refuse  */
 232                                 /* further access.                                      */
 233                     
 234                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
 235                                 SCpnt = end_scsi_request(SCpnt, 0, this_count);
 236                                 requeue_sr_request(SCpnt);
 237                                 return;
 238                         }
 239                 }
 240             
 241                 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
 242                         printk("CD-ROM error: ");
 243                         print_sense("sr", SCpnt);
 244                         printk("command was: ");
 245                         print_command(SCpnt->cmnd);
 246                         if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
 247                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
 248                                 requeue_sr_request(SCpnt);
 249                                 result = 0;
 250                                 return;
 251                         } else {
 252                           SCpnt = end_scsi_request(SCpnt, 0, this_count);
 253                           requeue_sr_request(SCpnt); /* Do next request */
 254                           return;
 255                         }
 256 
 257                 }
 258 
 259                 if (SCpnt->sense_buffer[2] == NOT_READY) {
 260                         printk("CDROM not ready.  Make sure you have a disc in the drive.\n");
 261                         SCpnt = end_scsi_request(SCpnt, 0, this_count);
 262                         requeue_sr_request(SCpnt); /* Do next request */
 263                         return;
 264                 };
 265               }
 266         
 267         /* We only get this far if we have an error we have not recognized */
 268         if(result) {
 269           printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", 
 270                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host->host_no, 
 271                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
 272                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
 273                  result);
 274             
 275           if (status_byte(result) == CHECK_CONDITION)
 276                   print_sense("sr", SCpnt);
 277           
 278           SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
 279           requeue_sr_request(SCpnt);
 280   }
 281 }
 282 
 283 /*
 284  * Here I tried to implement better support for PhotoCD's.
 285  * 
 286  * Much of this has do be done with vendor-specific SCSI-commands.
 287  * So I have to complete it step by step. Useful information is welcome.
 288  *
 289  * Actually works:
 290  *   - NEC:     Detection and support of multisession CD's. Special handling
 291  *              for XA-disks is not necessary.
 292  *     
 293  *   - TOSHIBA: setting density is done here now, mounting PhotoCD's should
 294  *              work now without running the program "set_density"
 295  *              People reported that it is necessary to eject and reinsert
 296  *              the CD after the set-density call to get this working for
 297  *              old drives.
 298  *              And some very new drives don't need this call any more...
 299  *              Multisession CD's are supported too.
 300  *
 301  * Dec 1994: completely rewritten, uses kernel_scsi_ioctl() now
 302  *
 303  *   kraxel@cs.tu-berlin.de (Gerd Knorr)
 304  */
 305 
 306 static void sr_photocd(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 307 {
 308   unsigned long   sector,min,sec,frame;
 309   unsigned char   buf[40];
 310   int             rc;
 311 
 312   if (!suser()) {
 313     /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed for me.
 314      * That's why mpcd_sector will be initialized with zero, because I'm not
 315      * able to get the right value. Necessary only if access_count is 1, else
 316      * no disk change happened since the last call of this function and we can
 317      * keep the old value.
 318      */
 319     if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
 320       scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
 321     return;
 322   }
 323   
 324   switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
 325 
 326   case SCSI_MAN_NEC:
 327 #ifdef DEBUG
 328     printk("sr_photocd: use NEC code\n");
 329 #endif
 330     memset(buf,0,40);
 331     *((unsigned long*)buf)   = 0;
 332     *((unsigned long*)buf+1) = 0x16;
 333     buf[8+0] = 0xde;
 334     buf[8+1] = 0x03;
 335     buf[8+2] = 0xb0;
 336     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 337                            SCSI_IOCTL_SEND_COMMAND, buf);
 338     if (rc != 0) {
 339       printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
 340       sector = 0;
 341     } else {
 342       min   = (unsigned long)buf[8+15]/16*10 + (unsigned long)buf[8+15]%16;
 343       sec   = (unsigned long)buf[8+16]/16*10 + (unsigned long)buf[8+16]%16;
 344       frame = (unsigned long)buf[8+17]/16*10 + (unsigned long)buf[8+17]%16;
 345       sector = min*60*75 + sec*75 + frame;
 346 #ifdef DEBUG
 347       if (sector) {
 348         printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
 349       }
 350 #endif
 351     }
 352     break;
 353 
 354   case SCSI_MAN_TOSHIBA:
 355 #ifdef DEBUG
 356     printk("sr_photocd: use TOSHIBA code\n");
 357 #endif
 358     
 359     /* first I do a set_density-call (for reading XA-sectors) ... */
 360     memset(buf,0,40);
 361     *((unsigned long*)buf)   = 12;
 362     *((unsigned long*)buf+1) = 12;
 363     buf[8+0] = 0x15;
 364     buf[8+1] = (1 << 4);
 365     buf[8+4] = 12;
 366     buf[14+ 3] = 0x08;
 367     buf[14+ 4] = 0x83;
 368     buf[14+10] = 0x08;
 369     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 370                            SCSI_IOCTL_SEND_COMMAND, buf);
 371     if (rc != 0) {
 372       printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
 373     }
 374 
 375     /* ... and then I ask, if there is a multisession-Disk */
 376     memset(buf,0,40);
 377     *((unsigned long*)buf)   = 0;
 378     *((unsigned long*)buf+1) = 4;
 379     buf[8+0] = 0xc7;
 380     buf[8+1] = 3;
 381     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 382                            SCSI_IOCTL_SEND_COMMAND, buf);
 383     if (rc != 0) {
 384       printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
 385       sector = 0;
 386     } else {
 387       min   = (unsigned long)buf[8+1]/16*10 + (unsigned long)buf[8+1]%16;
 388       sec   = (unsigned long)buf[8+2]/16*10 + (unsigned long)buf[8+2]%16;
 389       frame = (unsigned long)buf[8+3]/16*10 + (unsigned long)buf[8+3]%16;
 390       sector = min*60*75 + sec*75 + frame;
 391       if (sector) {
 392         sector -= CD_BLOCK_OFFSET;
 393 #ifdef DEBUG
 394         printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
 395 #endif
 396       }
 397     }
 398     break;
 399 
 400   case SCSI_MAN_UNKNOWN:
 401   default:
 402 #ifdef DEBUG
 403     printk("sr_photocd: unknown drive, no special multisession code\n");
 404 #endif
 405     sector = 0;
 406     break; }
 407 
 408   scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
 409   return;
 410 }
 411 
 412 static int sr_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414         if(MINOR(inode->i_rdev) >= sr_template.nr_dev || 
 415            !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
 416 
 417         if (filp->f_mode & 2)  
 418             return -EROFS;
 419 
 420         check_disk_change(inode->i_rdev);
 421 
 422         if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
 423           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
 424         if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
 425           (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
 426 
 427         /* If this device did not have media in the drive at boot time, then
 428            we would have been unable to get the sector size.  Check to see if
 429            this is the case, and try again.
 430            */
 431 
 432         if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
 433           get_sectorsize(MINOR(inode->i_rdev));
 434 
 435 #if 1   /* don't use for now - it doesn't seem to work for everybody */
 436         sr_photocd(inode);
 437 #endif
 438 
 439         return 0;
 440 }
 441 
 442 
 443 /*
 444  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
 445  * is to take block device requests, and translate them to SCSI commands.
 446  */
 447         
 448 static void do_sr_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450   Scsi_Cmnd * SCpnt = NULL;
 451   struct request * req = NULL;
 452   unsigned long flags;
 453   int flag = 0;
 454 
 455   while (1==1){
 456     save_flags(flags);
 457     cli();
 458     if (CURRENT != NULL && CURRENT->dev == -1) {
 459       restore_flags(flags);
 460       return;
 461     };
 462     
 463     INIT_SCSI_REQUEST;
 464 
 465     if (flag++ == 0)
 466       SCpnt = allocate_device(&CURRENT,
 467                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 468     else SCpnt = NULL;
 469     restore_flags(flags);
 470 
 471 /* This is a performance enhancement.  We dig down into the request list and
 472    try and find a queueable request (i.e. device not busy, and host able to
 473    accept another command.  If we find one, then we queue it. This can
 474    make a big difference on systems with more than one disk drive.  We want
 475    to have the interrupts off when monkeying with the request list, because
 476    otherwise the kernel might try and slip in a request in between somewhere. */
 477 
 478     if (!SCpnt && sr_template.nr_dev > 1){
 479       struct request *req1;
 480       req1 = NULL;
 481       save_flags(flags);
 482       cli();
 483       req = CURRENT;
 484       while(req){
 485         SCpnt = request_queueable(req,
 486                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 487         if(SCpnt) break;
 488         req1 = req;
 489         req = req->next;
 490       };
 491       if (SCpnt && req->dev == -1) {
 492         if (req == CURRENT) 
 493           CURRENT = CURRENT->next;
 494         else
 495           req1->next = req->next;
 496       };
 497       restore_flags(flags);
 498     };
 499     
 500     if (!SCpnt)
 501       return; /* Could not find anything to do */
 502     
 503   wake_up(&wait_for_request);
 504 
 505 /* Queue command */
 506   requeue_sr_request(SCpnt);
 507   };  /* While */
 508 }    
 509 
 510 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 511 {
 512         unsigned int dev, block, realcount;
 513         unsigned char cmd[10], *buffer, tries;
 514         int this_count, start, end_rec;
 515 
 516         tries = 2;
 517 
 518       repeat:
 519         if(!SCpnt || SCpnt->request.dev <= 0) {
 520           do_sr_request();
 521           return;
 522         }
 523 
 524         dev =  MINOR(SCpnt->request.dev);
 525         block = SCpnt->request.sector;  
 526         buffer = NULL;
 527         this_count = 0;
 528 
 529         if (dev >= sr_template.nr_dev)
 530                 {
 531                 /* printk("CD-ROM request error: invalid device.\n");                   */
 532                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 533                 tries = 2;
 534                 goto repeat;
 535                 }
 536 
 537         if (!scsi_CDs[dev].use)
 538                 {
 539                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 540                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 541                 tries = 2;
 542                 goto repeat;
 543                 }
 544 
 545         if (scsi_CDs[dev].device->changed)
 546                 {
 547 /* 
 548  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 549  */
 550                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 551                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 552                 tries = 2;
 553                 goto repeat;
 554                 }
 555         
 556         switch (SCpnt->request.cmd)
 557                 {
 558                 case WRITE:             
 559                         SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 560                         goto repeat;
 561                         break;
 562                 case READ : 
 563                         cmd[0] = READ_6;
 564                         break;
 565                 default : 
 566                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 567                 }
 568         
 569         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 570 
 571 /*
 572            Now do the grungy work of figuring out which sectors we need, and
 573            where in memory we are going to put them.
 574 
 575            The variables we need are:
 576 
 577            this_count= number of 512 byte sectors being read 
 578            block     = starting cdrom sector to read.
 579            realcount = # of cdrom sectors to read
 580 
 581            The major difference between a scsi disk and a scsi cdrom
 582 is that we will always use scatter-gather if we can, because we can
 583 work around the fact that the buffer cache has a block size of 1024,
 584 and we have 2048 byte sectors.  This code should work for buffers that
 585 are any multiple of 512 bytes long.  */
 586 
 587 #if 1
 588         /* Here we redirect the volume descriptor block of the CD-ROM.
 589          * Necessary for multisession CD's, until the isofs-routines
 590          * handle this via the CDROMMULTISESSION_SYS call
 591          */
 592         if (block >= 64 && block < 68) {
 593           block += scsi_CDs[dev].mpcd_sector*4; }
 594 #endif
 595         
 596         SCpnt->use_sg = 0;
 597 
 598         if (SCpnt->host->sg_tablesize > 0 &&
 599             (!need_isa_buffer ||
 600             dma_free_sectors >= 10)) {
 601           struct buffer_head * bh;
 602           struct scatterlist * sgpnt;
 603           int count, this_count_max;
 604           bh = SCpnt->request.bh;
 605           this_count = 0;
 606           count = 0;
 607           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 608           /* Calculate how many links we can use.  First see if we need
 609            a padding record at the start */
 610           this_count = SCpnt->request.sector % 4;
 611           if(this_count) count++;
 612           while(bh && count < SCpnt->host->sg_tablesize) {
 613             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 614             this_count += (bh->b_size >> 9);
 615             count++;
 616             bh = bh->b_reqnext;
 617           };
 618           /* Fix up in case of an odd record at the end */
 619           end_rec = 0;
 620           if(this_count % 4) {
 621             if (count < SCpnt->host->sg_tablesize) {
 622               count++;
 623               end_rec = (4 - (this_count % 4)) << 9;
 624               this_count += 4 - (this_count % 4);
 625             } else {
 626               count--;
 627               this_count -= (this_count % 4);
 628             };
 629           };
 630           SCpnt->use_sg = count;  /* Number of chains */
 631           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 632           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 633             count = count << 1;
 634           SCpnt->sglist_len = count;
 635           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 636           if (!sgpnt) {
 637             printk("Warning - running *really* short on DMA buffers\n");
 638             SCpnt->use_sg = 0;  /* No memory left - bail out */
 639           } else {
 640             buffer = (unsigned char *) sgpnt;
 641             count = 0;
 642             bh = SCpnt->request.bh;
 643             if(SCpnt->request.sector % 4) {
 644               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 645               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 646               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 647               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 648                                                                   if needed */
 649               count++;
 650             };
 651             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 652                 count++, bh = bh->b_reqnext) {
 653               if (bh) { /* Need a placeholder at the end of the record? */
 654                 sgpnt[count].address = bh->b_data;
 655                 sgpnt[count].length = bh->b_size;
 656                 sgpnt[count].alt_address = NULL;
 657               } else {
 658                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 659                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 660                 sgpnt[count].length = end_rec;
 661                 sgpnt[count].alt_address = sgpnt[count].address;
 662                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 663                 break;
 664               };
 665               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 666                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 667                 sgpnt[count].alt_address = sgpnt[count].address;
 668                 /* We try and avoid exhausting the DMA pool, since it is easier
 669                    to control usage here.  In other places we might have a more
 670                    pressing need, and we would be screwed if we ran out */
 671                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 672                   sgpnt[count].address = NULL;
 673                 } else {
 674                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 675                 };
 676 /* If we start running low on DMA buffers, we abort the scatter-gather
 677    operation, and free all of the memory we have allocated.  We want to
 678    ensure that all scsi operations are able to do at least a non-scatter/gather
 679    operation */
 680                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 681                   printk("Warning: Running low on SCSI DMA buffers");
 682                   /* Try switching back to a non scatter-gather operation. */
 683                   while(--count >= 0){
 684                     if(sgpnt[count].alt_address) 
 685                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 686                   };
 687                   SCpnt->use_sg = 0;
 688                   scsi_free(buffer, SCpnt->sglist_len);
 689                   break;
 690                 }; /* if address == NULL */
 691               };  /* if need DMA fixup */
 692             };  /* for loop to fill list */
 693 #ifdef DEBUG
 694             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 695                    this_count, 
 696                    SCpnt->request.current_nr_sectors,
 697                    SCpnt->request.nr_sectors);
 698             for(count=0; count<SCpnt->use_sg; count++)
 699               printk("SGlist: %d %x %x %x\n", count,
 700                      sgpnt[count].address, 
 701                      sgpnt[count].alt_address, 
 702                      sgpnt[count].length);
 703 #endif
 704           };  /* Able to allocate scatter-gather list */
 705         };
 706         
 707         if (SCpnt->use_sg == 0){
 708           /* We cannot use scatter-gather.  Do this the old fashion way */
 709           if (!SCpnt->request.bh)       
 710             this_count = SCpnt->request.nr_sectors;
 711           else
 712             this_count = (SCpnt->request.bh->b_size >> 9);
 713           
 714           start = block % 4;
 715           if (start)
 716             {                             
 717               this_count = ((this_count > 4 - start) ? 
 718                             (4 - start) : (this_count));
 719               buffer = (unsigned char *) scsi_malloc(2048);
 720             } 
 721           else if (this_count < 4)
 722             {
 723               buffer = (unsigned char *) scsi_malloc(2048);
 724             }
 725           else
 726             {
 727               this_count -= this_count % 4;
 728               buffer = (unsigned char *) SCpnt->request.buffer;
 729               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 730                   (SCpnt->host->unchecked_isa_dma))
 731                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 732             }
 733         };
 734 
 735         if (scsi_CDs[dev].sector_size == 2048)
 736           block = block >> 2; /* These are the sectors that the cdrom uses */
 737         else
 738           block = block & 0xfffffffc;
 739 
 740         realcount = (this_count + 3) / 4;
 741 
 742         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 743 
 744         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 745                 {
 746                 if (realcount > 0xffff)
 747                         {
 748                         realcount = 0xffff;
 749                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 750                         }
 751 
 752                 cmd[0] += READ_10 - READ_6 ;
 753                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 754                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 755                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 756                 cmd[5] = (unsigned char) block & 0xff;
 757                 cmd[6] = cmd[9] = 0;
 758                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 759                 cmd[8] = (unsigned char) realcount & 0xff;
 760                 }
 761         else
 762                 {
 763                   if (realcount > 0xff)
 764                     {
 765                       realcount = 0xff;
 766                       this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 767                     }
 768                   
 769                   cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 770                   cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 771                   cmd[3] = (unsigned char) block & 0xff;
 772                   cmd[4] = (unsigned char) realcount;
 773                   cmd[5] = 0;
 774                 }   
 775 
 776 #ifdef DEBUG
 777         { 
 778           int i;
 779           printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 780           printk("Use sg: %d\n", SCpnt->use_sg);
 781           printk("Dumping command: ");
 782           for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 783           printk("\n");
 784         };
 785 #endif
 786 
 787 /* Some dumb host adapters can speed transfers by knowing the
 788  * minimum transfersize in advance.
 789  *
 790  * We shouldn't disconnect in the middle of a sector, but the cdrom
 791  * sector size can be larger than the size of a buffer and the
 792  * transfer may be split to the size of a buffer.  So it's safe to
 793  * assume that we can at least transfer the minimum of the buffer
 794  * size (1024) and the sector size between each connect / disconnect.
 795  */
 796 
 797         SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
 798                         1024 : scsi_CDs[dev].sector_size;
 799 
 800         SCpnt->this_count = this_count;
 801         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 802                      realcount * scsi_CDs[dev].sector_size, 
 803                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 804 }
 805 
 806 static int sr_detect(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 807   
 808   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
 809 
 810   printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", 
 811          sr_template.dev_noticed++,
 812          SDp->host->host_no , SDp->id, SDp->lun); 
 813 
 814          return 1;
 815 }
 816 
 817 static int sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 818   Scsi_CD * cpnt;
 819   int i;
 820   
 821   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
 822   
 823   if (sr_template.nr_dev >= sr_template.dev_max)
 824     {
 825         SDp->attached--;
 826         return 1;
 827     }
 828   
 829   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
 830     if(!cpnt->device) break;
 831   
 832   if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
 833   
 834   SDp->scsi_request_fn = do_sr_request;
 835   scsi_CDs[i].device = SDp;
 836   sr_template.nr_dev++;
 837   if(sr_template.nr_dev > sr_template.dev_max)
 838     panic ("scsi_devices corrupt (sr)");
 839   return 0;
 840 }
 841      
 842 
 843 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 844 {
 845   struct request * req;
 846   
 847   req = &SCpnt->request;
 848   req->dev = 0xfffe; /* Busy, but indicate request done */
 849   
 850   if (req->sem != NULL) {
 851     up(req->sem);
 852   }
 853 }
 854 
 855 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 856   unsigned char cmd[10];
 857   unsigned char *buffer;
 858   int the_result, retries;
 859   Scsi_Cmnd * SCpnt;
 860   
 861   buffer = (unsigned char *) scsi_malloc(512);
 862   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 863 
 864   retries = 3;
 865   do {
 866     cmd[0] = READ_CAPACITY;
 867     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 868     memset ((void *) &cmd[2], 0, 8);
 869     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 870     SCpnt->cmd_len = 0;
 871     
 872     memset(buffer, 0, 8);
 873 
 874     scsi_do_cmd (SCpnt,
 875                  (void *) cmd, (void *) buffer,
 876                  512, sr_init_done,  SR_TIMEOUT,
 877                  MAX_RETRIES);
 878     
 879     if (current == task[0])
 880       while(SCpnt->request.dev != 0xfffe);
 881     else
 882       if (SCpnt->request.dev != 0xfffe){
 883         struct semaphore sem = MUTEX_LOCKED;
 884         SCpnt->request.sem = &sem;
 885         down(&sem);
 886         /* Hmm.. Have to ask about this */
 887         while (SCpnt->request.dev != 0xfffe) schedule();
 888       };
 889     
 890     the_result = SCpnt->result;
 891     retries--;
 892     
 893   } while(the_result && retries);
 894   
 895   SCpnt->request.dev = -1;  /* Mark as not busy */
 896   
 897   wake_up(&SCpnt->device->device_wait); 
 898 
 899   if (the_result) {
 900     scsi_CDs[i].capacity = 0x1fffff;
 901     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 902     scsi_CDs[i].needs_sector_size = 1;
 903   } else {
 904     scsi_CDs[i].capacity = (buffer[0] << 24) |
 905       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 906     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 907       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 908     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 909     if(scsi_CDs[i].sector_size != 2048 && 
 910        scsi_CDs[i].sector_size != 512) {
 911       printk ("scd%d : unsupported sector size %d.\n",
 912               i, scsi_CDs[i].sector_size);
 913       scsi_CDs[i].capacity = 0;
 914       scsi_CDs[i].needs_sector_size = 1;
 915     };
 916     if(scsi_CDs[i].sector_size == 2048)
 917       scsi_CDs[i].capacity *= 4;
 918     scsi_CDs[i].needs_sector_size = 0;
 919   };
 920   scsi_free(buffer, 512);
 921 }
 922 
 923 static void sr_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 924 {
 925         int i;
 926         static int sr_registered = 0;
 927 
 928         if(sr_template.dev_noticed == 0) return;
 929 
 930         if(!sr_registered) {
 931           if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 932             printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 933             return;
 934           }
 935           sr_registered++;
 936         }
 937 
 938         
 939         if (scsi_CDs) return;
 940         sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
 941         scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
 942         memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
 943 
 944         sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
 945         memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
 946 
 947         sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 948                                                  sizeof(int), GFP_ATOMIC);
 949         for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
 950         blksize_size[MAJOR_NR] = sr_blocksizes;
 951 
 952 }
 953 
 954 void sr_finish()
     /* [previous][next][first][last][top][bottom][index][help] */
 955 {
 956   int i;
 957 
 958         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 959         blk_size[MAJOR_NR] = sr_sizes;  
 960 
 961         for (i = 0; i < sr_template.nr_dev; ++i)
 962                 {
 963                   /* If we have already seen this, then skip it.  Comes up
 964                      with loadable modules. */
 965                   if (scsi_CDs[i].capacity) continue;
 966                   scsi_CDs[i].capacity = 0x1fffff;
 967                   scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 968                   scsi_CDs[i].needs_sector_size = 1;
 969 #if 0
 970                   /* seems better to leave this for later */
 971                   get_sectorsize(i);
 972                   printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
 973 #endif
 974                   scsi_CDs[i].use = 1;
 975                   scsi_CDs[i].ten = 1;
 976                   scsi_CDs[i].remap = 1;
 977                   sr_sizes[i] = scsi_CDs[i].capacity;
 978                 }
 979 
 980 
 981         /* If our host adapter is capable of scatter-gather, then we increase
 982            the read-ahead to 16 blocks (32 sectors).  If not, we use
 983            a two block (4 sector) read ahead. */
 984         if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
 985           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 986         else
 987           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 988 
 989         return;
 990 }       
 991 
 992 static void sr_detach(Scsi_Device * SDp)
     /* [previous][next][first][last][top][bottom][index][help] */
 993 {
 994   Scsi_CD * cpnt;
 995   int i, major;
 996   
 997   major = MAJOR_NR << 8;
 998 
 999   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
1000     if(cpnt->device == SDp) {
1001       /*
1002        * Since the cdrom is read-only, no need to sync the device.
1003        * We should be kind to our buffer cache, however.
1004        */
1005       invalidate_inodes(major | i);
1006       invalidate_buffers(major | i);
1007 
1008       /*
1009        * Reset things back to a sane state so that one can re-load a new
1010        * driver (perhaps the same one).
1011        */
1012       cpnt->device = NULL;
1013       cpnt->capacity = 0;
1014       SDp->attached--;
1015       sr_template.nr_dev--;
1016       sr_template.dev_noticed--;
1017       sr_sizes[i] = 0;
1018       return;
1019     }
1020   return;
1021 }

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