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_done
  5. sr_photocd
  6. sr_open
  7. do_sr_request
  8. requeue_sr_request
  9. sr_detect
  10. sr_attach
  11. sr_init_done
  12. get_sectorsize
  13. sr_init
  14. sr_finish

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

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