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   int flag = 0;
 435 
 436   while (1==1){
 437     cli();
 438     if (CURRENT != NULL && CURRENT->dev == -1) {
 439       sti();
 440       return;
 441     };
 442     
 443     INIT_SCSI_REQUEST;
 444 
 445     if (flag++ == 0)
 446       SCpnt = allocate_device(&CURRENT,
 447                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 448     else SCpnt = NULL;
 449     sti();
 450 
 451 /* This is a performance enhancement.  We dig down into the request list and
 452    try and find a queueable request (i.e. device not busy, and host able to
 453    accept another command.  If we find one, then we queue it. This can
 454    make a big difference on systems with more than one disk drive.  We want
 455    to have the interrupts off when monkeying with the request list, because
 456    otherwise the kernel might try and slip in a request in between somewhere. */
 457 
 458     if (!SCpnt && sr_template.nr_dev > 1){
 459       struct request *req1;
 460       req1 = NULL;
 461       cli();
 462       req = CURRENT;
 463       while(req){
 464         SCpnt = request_queueable(req,
 465                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 466         if(SCpnt) break;
 467         req1 = req;
 468         req = req->next;
 469       };
 470       if (SCpnt && req->dev == -1) {
 471         if (req == CURRENT) 
 472           CURRENT = CURRENT->next;
 473         else
 474           req1->next = req->next;
 475       };
 476       sti();
 477     };
 478     
 479     if (!SCpnt)
 480       return; /* Could not find anything to do */
 481     
 482   wake_up(&wait_for_request);
 483 
 484 /* Queue command */
 485   requeue_sr_request(SCpnt);
 486   };  /* While */
 487 }    
 488 
 489 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 490 {
 491         unsigned int dev, block, realcount;
 492         unsigned char cmd[10], *buffer, tries;
 493         int this_count, start, end_rec;
 494 
 495         tries = 2;
 496 
 497       repeat:
 498         if(!SCpnt || SCpnt->request.dev <= 0) {
 499           do_sr_request();
 500           return;
 501         }
 502 
 503         dev =  MINOR(SCpnt->request.dev);
 504         block = SCpnt->request.sector;  
 505         buffer = NULL;
 506         this_count = 0;
 507 
 508         if (dev >= sr_template.nr_dev)
 509                 {
 510                 /* printk("CD-ROM request error: invalid device.\n");                   */
 511                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 512                 tries = 2;
 513                 goto repeat;
 514                 }
 515 
 516         if (!scsi_CDs[dev].use)
 517                 {
 518                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 519                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 520                 tries = 2;
 521                 goto repeat;
 522                 }
 523 
 524         if (scsi_CDs[dev].device->changed)
 525                 {
 526 /* 
 527  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 528  */
 529                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 530                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 531                 tries = 2;
 532                 goto repeat;
 533                 }
 534         
 535         switch (SCpnt->request.cmd)
 536                 {
 537                 case WRITE:             
 538                         SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 539                         goto repeat;
 540                         break;
 541                 case READ : 
 542                         cmd[0] = READ_6;
 543                         break;
 544                 default : 
 545                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 546                 }
 547         
 548         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 549 
 550 /*
 551            Now do the grungy work of figuring out which sectors we need, and
 552            where in memory we are going to put them.
 553 
 554            The variables we need are:
 555 
 556            this_count= number of 512 byte sectors being read 
 557            block     = starting cdrom sector to read.
 558            realcount = # of cdrom sectors to read
 559 
 560            The major difference between a scsi disk and a scsi cdrom
 561 is that we will always use scatter-gather if we can, because we can
 562 work around the fact that the buffer cache has a block size of 1024,
 563 and we have 2048 byte sectors.  This code should work for buffers that
 564 are any multiple of 512 bytes long.  */
 565 
 566         /* this is for support of multisession-CD's */ 
 567         if (block >= 64 && block < 68) {
 568           block += scsi_CDs[dev].mpcd_sector*4; }
 569 
 570         SCpnt->use_sg = 0;
 571 
 572         if (SCpnt->host->sg_tablesize > 0 &&
 573             (!need_isa_buffer ||
 574             dma_free_sectors >= 10)) {
 575           struct buffer_head * bh;
 576           struct scatterlist * sgpnt;
 577           int count, this_count_max;
 578           bh = SCpnt->request.bh;
 579           this_count = 0;
 580           count = 0;
 581           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 582           /* Calculate how many links we can use.  First see if we need
 583            a padding record at the start */
 584           this_count = SCpnt->request.sector % 4;
 585           if(this_count) count++;
 586           while(bh && count < SCpnt->host->sg_tablesize) {
 587             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 588             this_count += (bh->b_size >> 9);
 589             count++;
 590             bh = bh->b_reqnext;
 591           };
 592           /* Fix up in case of an odd record at the end */
 593           end_rec = 0;
 594           if(this_count % 4) {
 595             if (count < SCpnt->host->sg_tablesize) {
 596               count++;
 597               end_rec = (4 - (this_count % 4)) << 9;
 598               this_count += 4 - (this_count % 4);
 599             } else {
 600               count--;
 601               this_count -= (this_count % 4);
 602             };
 603           };
 604           SCpnt->use_sg = count;  /* Number of chains */
 605           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 606           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 607             count = count << 1;
 608           SCpnt->sglist_len = count;
 609           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 610           if (!sgpnt) {
 611             printk("Warning - running *really* short on DMA buffers\n");
 612             SCpnt->use_sg = 0;  /* No memory left - bail out */
 613           } else {
 614             buffer = (unsigned char *) sgpnt;
 615             count = 0;
 616             bh = SCpnt->request.bh;
 617             if(SCpnt->request.sector % 4) {
 618               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 619               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 620               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 621               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 622                                                                   if needed */
 623               count++;
 624             };
 625             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 626                 count++, bh = bh->b_reqnext) {
 627               if (bh) { /* Need a placeholder at the end of the record? */
 628                 sgpnt[count].address = bh->b_data;
 629                 sgpnt[count].length = bh->b_size;
 630                 sgpnt[count].alt_address = NULL;
 631               } else {
 632                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 633                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 634                 sgpnt[count].length = end_rec;
 635                 sgpnt[count].alt_address = sgpnt[count].address;
 636                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 637                 break;
 638               };
 639               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 640                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 641                 sgpnt[count].alt_address = sgpnt[count].address;
 642                 /* We try and avoid exhausting the DMA pool, since it is easier
 643                    to control usage here.  In other places we might have a more
 644                    pressing need, and we would be screwed if we ran out */
 645                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 646                   sgpnt[count].address = NULL;
 647                 } else {
 648                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 649                 };
 650 /* If we start running low on DMA buffers, we abort the scatter-gather
 651    operation, and free all of the memory we have allocated.  We want to
 652    ensure that all scsi operations are able to do at least a non-scatter/gather
 653    operation */
 654                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 655                   printk("Warning: Running low on SCSI DMA buffers");
 656                   /* Try switching back to a non scatter-gather operation. */
 657                   while(--count >= 0){
 658                     if(sgpnt[count].alt_address) 
 659                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 660                   };
 661                   SCpnt->use_sg = 0;
 662                   scsi_free(buffer, SCpnt->sglist_len);
 663                   break;
 664                 }; /* if address == NULL */
 665               };  /* if need DMA fixup */
 666             };  /* for loop to fill list */
 667 #ifdef DEBUG
 668             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 669                    this_count, 
 670                    SCpnt->request.current_nr_sectors,
 671                    SCpnt->request.nr_sectors);
 672             for(count=0; count<SCpnt->use_sg; count++)
 673               printk("SGlist: %d %x %x %x\n", count,
 674                      sgpnt[count].address, 
 675                      sgpnt[count].alt_address, 
 676                      sgpnt[count].length);
 677 #endif
 678           };  /* Able to allocate scatter-gather list */
 679         };
 680         
 681         if (SCpnt->use_sg == 0){
 682           /* We cannot use scatter-gather.  Do this the old fashion way */
 683           if (!SCpnt->request.bh)       
 684             this_count = SCpnt->request.nr_sectors;
 685           else
 686             this_count = (SCpnt->request.bh->b_size >> 9);
 687           
 688           start = block % 4;
 689           if (start)
 690             {                             
 691               this_count = ((this_count > 4 - start) ? 
 692                             (4 - start) : (this_count));
 693               buffer = (unsigned char *) scsi_malloc(2048);
 694             } 
 695           else if (this_count < 4)
 696             {
 697               buffer = (unsigned char *) scsi_malloc(2048);
 698             }
 699           else
 700             {
 701               this_count -= this_count % 4;
 702               buffer = (unsigned char *) SCpnt->request.buffer;
 703               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 704                   (SCpnt->host->unchecked_isa_dma))
 705                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 706             }
 707         };
 708 
 709         if (scsi_CDs[dev].sector_size == 2048)
 710           block = block >> 2; /* These are the sectors that the cdrom uses */
 711         else
 712           block = block & 0xfffffffc;
 713 
 714         realcount = (this_count + 3) / 4;
 715 
 716         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 717 
 718         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 719                 {
 720                 if (realcount > 0xffff)
 721                         {
 722                         realcount = 0xffff;
 723                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 724                         }
 725 
 726                 cmd[0] += READ_10 - READ_6 ;
 727                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 728                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 729                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 730                 cmd[5] = (unsigned char) block & 0xff;
 731                 cmd[6] = cmd[9] = 0;
 732                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 733                 cmd[8] = (unsigned char) realcount & 0xff;
 734                 }
 735         else
 736                 {
 737                   if (realcount > 0xff)
 738                     {
 739                       realcount = 0xff;
 740                       this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 741                     }
 742                   
 743                   cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 744                   cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 745                   cmd[3] = (unsigned char) block & 0xff;
 746                   cmd[4] = (unsigned char) realcount;
 747                   cmd[5] = 0;
 748                 }   
 749 
 750 #ifdef DEBUG
 751         { 
 752           int i;
 753           printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 754           printk("Use sg: %d\n", SCpnt->use_sg);
 755           printk("Dumping command: ");
 756           for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 757           printk("\n");
 758         };
 759 #endif
 760 
 761 /* Some dumb host adapters can speed transfers by knowing the
 762  * minimum transfersize in advance.
 763  *
 764  * We shouldn't disconnect in the middle of a sector, but the cdrom
 765  * sector size can be larger than the size of a buffer and the
 766  * transfer may be split to the size of a buffer.  So it's safe to
 767  * assume that we can at least transfer the minimum of the buffer
 768  * size (1024) and the sector size between each connect / disconnect.
 769  */
 770 
 771         SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
 772                         1024 : scsi_CDs[dev].sector_size;
 773 
 774         SCpnt->this_count = this_count;
 775         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 776                      realcount * scsi_CDs[dev].sector_size, 
 777                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 778 }
 779 
 780 static int sr_detect(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 781   
 782   /* We do not support attaching loadable devices yet. */
 783   if(scsi_loadable_module_flag) return 0;
 784   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
 785 
 786   printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", 
 787          sr_template.dev_noticed++,
 788          SDp->host->host_no , SDp->id, SDp->lun); 
 789 
 790          return 1;
 791 }
 792 
 793 static void sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 794   Scsi_CD * cpnt;
 795   int i;
 796   
 797   /* We do not support attaching loadable devices yet. */
 798   
 799   if(scsi_loadable_module_flag) return;
 800   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return;
 801   
 802   if (sr_template.nr_dev >= sr_template.dev_max)
 803     panic ("scsi_devices corrupt (sr)");
 804   
 805   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
 806     if(!cpnt->device) break;
 807   
 808   if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
 809   
 810   SDp->scsi_request_fn = do_sr_request;
 811   scsi_CDs[i].device = SDp;
 812   sr_template.nr_dev++;
 813   if(sr_template.nr_dev > sr_template.dev_max)
 814     panic ("scsi_devices corrupt (sr)");
 815 }
 816      
 817 
 818 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 819 {
 820   struct request * req;
 821   
 822   req = &SCpnt->request;
 823   req->dev = 0xfffe; /* Busy, but indicate request done */
 824   
 825   if (req->sem != NULL) {
 826     up(req->sem);
 827   }
 828 }
 829 
 830 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 831   unsigned char cmd[10];
 832   unsigned char *buffer;
 833   int the_result, retries;
 834   Scsi_Cmnd * SCpnt;
 835   
 836   buffer = (unsigned char *) scsi_malloc(512);
 837   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 838 
 839   retries = 3;
 840   do {
 841     cmd[0] = READ_CAPACITY;
 842     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 843     memset ((void *) &cmd[2], 0, 8);
 844     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 845     SCpnt->cmd_len = 0;
 846     
 847     memset(buffer, 0, 8);
 848 
 849     scsi_do_cmd (SCpnt,
 850                  (void *) cmd, (void *) buffer,
 851                  512, sr_init_done,  SR_TIMEOUT,
 852                  MAX_RETRIES);
 853     
 854     if (current == task[0])
 855       while(SCpnt->request.dev != 0xfffe);
 856     else
 857       if (SCpnt->request.dev != 0xfffe){
 858         struct semaphore sem = MUTEX_LOCKED;
 859         SCpnt->request.sem = &sem;
 860         down(&sem);
 861         /* Hmm.. Have to ask about this */
 862         while (SCpnt->request.dev != 0xfffe) schedule();
 863       };
 864     
 865     the_result = SCpnt->result;
 866     retries--;
 867     
 868   } while(the_result && retries);
 869   
 870   SCpnt->request.dev = -1;  /* Mark as not busy */
 871   
 872   wake_up(&SCpnt->device->device_wait); 
 873 
 874   if (the_result) {
 875     scsi_CDs[i].capacity = 0x1fffff;
 876     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 877     scsi_CDs[i].needs_sector_size = 1;
 878   } else {
 879     scsi_CDs[i].capacity = (buffer[0] << 24) |
 880       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 881     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 882       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 883     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 884     if(scsi_CDs[i].sector_size != 2048 && 
 885        scsi_CDs[i].sector_size != 512) {
 886       printk ("scd%d : unsupported sector size %d.\n",
 887               i, scsi_CDs[i].sector_size);
 888       scsi_CDs[i].capacity = 0;
 889       scsi_CDs[i].needs_sector_size = 1;
 890     };
 891     if(scsi_CDs[i].sector_size == 2048)
 892       scsi_CDs[i].capacity *= 4;
 893     scsi_CDs[i].needs_sector_size = 0;
 894   };
 895   scsi_free(buffer, 512);
 896 }
 897 
 898 static void sr_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 899 {
 900         int i;
 901         static int sr_registered = 0;
 902 
 903         if(sr_template.dev_noticed == 0) return;
 904 
 905         if(!sr_registered) {
 906           if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 907             printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 908             return;
 909           }
 910         }
 911 
 912         /* We do not support attaching loadable devices yet. */
 913         if(scsi_loadable_module_flag) return;
 914 
 915         sr_template.dev_max = sr_template.dev_noticed;
 916         scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD));
 917         memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
 918 
 919         sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int));
 920         memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
 921 
 922         sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 923                                                  sizeof(int));
 924         for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
 925         blksize_size[MAJOR_NR] = sr_blocksizes;
 926 
 927 }
 928 
 929 void sr_finish()
     /* [previous][next][first][last][top][bottom][index][help] */
 930 {
 931   int i;
 932 
 933         for (i = 0; i < sr_template.nr_dev; ++i)
 934                 {
 935                   get_sectorsize(i);
 936                   printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
 937                   scsi_CDs[i].use = 1;
 938                   scsi_CDs[i].ten = 1;
 939                   scsi_CDs[i].remap = 1;
 940                   sr_sizes[i] = scsi_CDs[i].capacity;
 941                 }
 942 
 943         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 944         blk_size[MAJOR_NR] = sr_sizes;  
 945 
 946         /* If our host adapter is capable of scatter-gather, then we increase
 947            the read-ahead to 16 blocks (32 sectors).  If not, we use
 948            a two block (4 sector) read ahead. */
 949         if(scsi_CDs[0].device->host->sg_tablesize)
 950           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 951         else
 952           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 953 
 954         return;
 955 }       

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