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

   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:
 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  *              People reported, that it is nessesary to eject and reinsert
 288  *              the CD after the set-density call to get this working for
 289  *              old drives.
 290  *              And some very new drives don't need this call any more...
 291  *              Multisession CD's are supported too.
 292  *
 293  * Dec 1994: completely rewritten, uses kernel_scsi_ioctl() now
 294  *
 295  *   kraxel@cs.tu-berlin.de (Gerd Knorr)
 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   unsigned char   buf[40];
 302   int             rc;
 303 
 304   if (!suser()) {
 305     /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND is'nt allowed for me.
 306      * That's why mpcd_sector will be initialized with zero, becauce I'm not
 307      * able to get the right value. Nessesary only if access_count is 1, else
 308      * no disk change happend since the last call of this function and we can
 309      * keep the old value.
 310      */
 311     if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
 312       scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
 313     return;
 314   }
 315   
 316   switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
 317 
 318   case SCSI_MAN_NEC:
 319 #ifdef DEBUG
 320     printk("sr_photocd: use NEC code\n");
 321 #endif
 322     memset(buf,0,40);
 323     *((unsigned long*)buf)   = 0;
 324     *((unsigned long*)buf+1) = 0x16;
 325     buf[8+0] = 0xde;
 326     buf[8+1] = 0x03;
 327     buf[8+2] = 0xb0;
 328     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 329                            SCSI_IOCTL_SEND_COMMAND, buf);
 330     if (rc != 0) {
 331       printk("sr_photocd: ioctl error: %i\n",rc);
 332       sector = 0;
 333     } else {
 334       min   = (unsigned long)buf[8+15]/16*10 + (unsigned long)buf[8+15]%16;
 335       sec   = (unsigned long)buf[8+16]/16*10 + (unsigned long)buf[8+16]%16;
 336       frame = (unsigned long)buf[8+17]/16*10 + (unsigned long)buf[8+17]%16;
 337       sector = min*60*75 + sec*75 + frame;
 338 #ifdef DEBUG
 339       if (sector) {
 340         printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
 341       }
 342 #endif
 343     }
 344     break;
 345 
 346   case SCSI_MAN_TOSHIBA:
 347 #ifdef DEBUG
 348     printk("sr_photocd: use TOSHIBA code\n");
 349 #endif
 350     
 351     /* first I do a set_density-call (for reading XA-sectors) ... */
 352     memset(buf,0,40);
 353     *((unsigned long*)buf)   = 12;
 354     *((unsigned long*)buf+1) = 12;
 355     buf[8+0] = 0x15;
 356     buf[8+1] = (1 << 4);
 357     buf[8+2] = 12;
 358     buf[14+ 3] = 0x08;
 359     buf[14+ 4] = 0x83;
 360     buf[14+10] = 0x08;
 361     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 362                            SCSI_IOCTL_SEND_COMMAND, buf);
 363     if (rc != 0) {
 364       printk("sr_photocd: ioctl error: %i\n",rc);
 365     }
 366 
 367     /* ... and then I ask, if there is a multisession-Disk */
 368     memset(buf,0,40);
 369     *((unsigned long*)buf)   = 0;
 370     *((unsigned long*)buf+1) = 4;
 371     buf[8+0] = 0xc7;
 372     buf[8+1] = 3;
 373     if (rc != 0) {
 374       printk("sr_photocd: ioctl error: %i\n",rc);
 375       sector = 0;
 376     } else {
 377       min   = (unsigned long)buf[8+1]/16*10 + (unsigned long)buf[8+1]%16;
 378       sec   = (unsigned long)buf[8+2]/16*10 + (unsigned long)buf[8+2]%16;
 379       frame = (unsigned long)buf[8+3]/16*10 + (unsigned long)buf[8+3]%16;
 380       sector = min*60*75 + sec*75 + frame;
 381       if (sector) {
 382         sector -= CD_BLOCK_OFFSET;
 383 #ifdef DEBUG
 384         printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
 385 #endif
 386       }
 387     }
 388     break;
 389 
 390   case SCSI_MAN_UNKNOWN:
 391   default:
 392 #ifdef DEBUG
 393     printk("sr_photocd: unknown drive, no special multisession code\n");
 394 #endif
 395     sector = 0;
 396     break; }
 397 
 398   scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
 399   return;
 400 }
 401 
 402 static int sr_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 403 {
 404         if(MINOR(inode->i_rdev) >= sr_template.nr_dev || 
 405            !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
 406 
 407         if (filp->f_mode & 2)  
 408             return -EROFS;
 409 
 410         check_disk_change(inode->i_rdev);
 411 
 412         if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
 413           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
 414 
 415         /* If this device did not have media in the drive at boot time, then
 416            we would have been unable to get the sector size.  Check to see if
 417            this is the case, and try again.
 418            */
 419 
 420         if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
 421           get_sectorsize(MINOR(inode->i_rdev));
 422 
 423 #if 1   /* don't use for now - it doesn't seem to work for everybody */
 424         sr_photocd(inode);
 425 #endif
 426 
 427         return 0;
 428 }
 429 
 430 
 431 /*
 432  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
 433  * is to take block device requests, and translate them to SCSI commands.
 434  */
 435         
 436 static void do_sr_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438   Scsi_Cmnd * SCpnt = NULL;
 439   struct request * req = NULL;
 440   unsigned long flags;
 441   int flag = 0;
 442 
 443   while (1==1){
 444     save_flags(flags);
 445     cli();
 446     if (CURRENT != NULL && CURRENT->dev == -1) {
 447       restore_flags(flags);
 448       return;
 449     };
 450     
 451     INIT_SCSI_REQUEST;
 452 
 453     if (flag++ == 0)
 454       SCpnt = allocate_device(&CURRENT,
 455                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 456     else SCpnt = NULL;
 457     restore_flags(flags);
 458 
 459 /* This is a performance enhancement.  We dig down into the request list and
 460    try and find a queueable request (i.e. device not busy, and host able to
 461    accept another command.  If we find one, then we queue it. This can
 462    make a big difference on systems with more than one disk drive.  We want
 463    to have the interrupts off when monkeying with the request list, because
 464    otherwise the kernel might try and slip in a request in between somewhere. */
 465 
 466     if (!SCpnt && sr_template.nr_dev > 1){
 467       struct request *req1;
 468       req1 = NULL;
 469       save_flags(flags);
 470       cli();
 471       req = CURRENT;
 472       while(req){
 473         SCpnt = request_queueable(req,
 474                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 475         if(SCpnt) break;
 476         req1 = req;
 477         req = req->next;
 478       };
 479       if (SCpnt && req->dev == -1) {
 480         if (req == CURRENT) 
 481           CURRENT = CURRENT->next;
 482         else
 483           req1->next = req->next;
 484       };
 485       restore_flags(flags);
 486     };
 487     
 488     if (!SCpnt)
 489       return; /* Could not find anything to do */
 490     
 491   wake_up(&wait_for_request);
 492 
 493 /* Queue command */
 494   requeue_sr_request(SCpnt);
 495   };  /* While */
 496 }    
 497 
 498 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 499 {
 500         unsigned int dev, block, realcount;
 501         unsigned char cmd[10], *buffer, tries;
 502         int this_count, start, end_rec;
 503 
 504         tries = 2;
 505 
 506       repeat:
 507         if(!SCpnt || SCpnt->request.dev <= 0) {
 508           do_sr_request();
 509           return;
 510         }
 511 
 512         dev =  MINOR(SCpnt->request.dev);
 513         block = SCpnt->request.sector;  
 514         buffer = NULL;
 515         this_count = 0;
 516 
 517         if (dev >= sr_template.nr_dev)
 518                 {
 519                 /* printk("CD-ROM request error: invalid device.\n");                   */
 520                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 521                 tries = 2;
 522                 goto repeat;
 523                 }
 524 
 525         if (!scsi_CDs[dev].use)
 526                 {
 527                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 528                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 529                 tries = 2;
 530                 goto repeat;
 531                 }
 532 
 533         if (scsi_CDs[dev].device->changed)
 534                 {
 535 /* 
 536  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 537  */
 538                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 539                 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 540                 tries = 2;
 541                 goto repeat;
 542                 }
 543         
 544         switch (SCpnt->request.cmd)
 545                 {
 546                 case WRITE:             
 547                         SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 548                         goto repeat;
 549                         break;
 550                 case READ : 
 551                         cmd[0] = READ_6;
 552                         break;
 553                 default : 
 554                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 555                 }
 556         
 557         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 558 
 559 /*
 560            Now do the grungy work of figuring out which sectors we need, and
 561            where in memory we are going to put them.
 562 
 563            The variables we need are:
 564 
 565            this_count= number of 512 byte sectors being read 
 566            block     = starting cdrom sector to read.
 567            realcount = # of cdrom sectors to read
 568 
 569            The major difference between a scsi disk and a scsi cdrom
 570 is that we will always use scatter-gather if we can, because we can
 571 work around the fact that the buffer cache has a block size of 1024,
 572 and we have 2048 byte sectors.  This code should work for buffers that
 573 are any multiple of 512 bytes long.  */
 574 
 575 #if 1
 576         /* Here we redirect the volume descriptor block of the CD-ROM.
 577          * Nessesary for multisession CD's, until the isofs-rotines
 578          * handle this via the CDROMMULTISESSION_SYS call
 579          */
 580         if (block >= 64 && block < 68) {
 581           block += scsi_CDs[dev].mpcd_sector*4; }
 582 #endif
 583         
 584         SCpnt->use_sg = 0;
 585 
 586         if (SCpnt->host->sg_tablesize > 0 &&
 587             (!need_isa_buffer ||
 588             dma_free_sectors >= 10)) {
 589           struct buffer_head * bh;
 590           struct scatterlist * sgpnt;
 591           int count, this_count_max;
 592           bh = SCpnt->request.bh;
 593           this_count = 0;
 594           count = 0;
 595           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 596           /* Calculate how many links we can use.  First see if we need
 597            a padding record at the start */
 598           this_count = SCpnt->request.sector % 4;
 599           if(this_count) count++;
 600           while(bh && count < SCpnt->host->sg_tablesize) {
 601             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 602             this_count += (bh->b_size >> 9);
 603             count++;
 604             bh = bh->b_reqnext;
 605           };
 606           /* Fix up in case of an odd record at the end */
 607           end_rec = 0;
 608           if(this_count % 4) {
 609             if (count < SCpnt->host->sg_tablesize) {
 610               count++;
 611               end_rec = (4 - (this_count % 4)) << 9;
 612               this_count += 4 - (this_count % 4);
 613             } else {
 614               count--;
 615               this_count -= (this_count % 4);
 616             };
 617           };
 618           SCpnt->use_sg = count;  /* Number of chains */
 619           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 620           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 621             count = count << 1;
 622           SCpnt->sglist_len = count;
 623           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 624           if (!sgpnt) {
 625             printk("Warning - running *really* short on DMA buffers\n");
 626             SCpnt->use_sg = 0;  /* No memory left - bail out */
 627           } else {
 628             buffer = (unsigned char *) sgpnt;
 629             count = 0;
 630             bh = SCpnt->request.bh;
 631             if(SCpnt->request.sector % 4) {
 632               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 633               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 634               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 635               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 636                                                                   if needed */
 637               count++;
 638             };
 639             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 640                 count++, bh = bh->b_reqnext) {
 641               if (bh) { /* Need a placeholder at the end of the record? */
 642                 sgpnt[count].address = bh->b_data;
 643                 sgpnt[count].length = bh->b_size;
 644                 sgpnt[count].alt_address = NULL;
 645               } else {
 646                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 647                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 648                 sgpnt[count].length = end_rec;
 649                 sgpnt[count].alt_address = sgpnt[count].address;
 650                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 651                 break;
 652               };
 653               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 654                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 655                 sgpnt[count].alt_address = sgpnt[count].address;
 656                 /* We try and avoid exhausting the DMA pool, since it is easier
 657                    to control usage here.  In other places we might have a more
 658                    pressing need, and we would be screwed if we ran out */
 659                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 660                   sgpnt[count].address = NULL;
 661                 } else {
 662                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 663                 };
 664 /* If we start running low on DMA buffers, we abort the scatter-gather
 665    operation, and free all of the memory we have allocated.  We want to
 666    ensure that all scsi operations are able to do at least a non-scatter/gather
 667    operation */
 668                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 669                   printk("Warning: Running low on SCSI DMA buffers");
 670                   /* Try switching back to a non scatter-gather operation. */
 671                   while(--count >= 0){
 672                     if(sgpnt[count].alt_address) 
 673                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 674                   };
 675                   SCpnt->use_sg = 0;
 676                   scsi_free(buffer, SCpnt->sglist_len);
 677                   break;
 678                 }; /* if address == NULL */
 679               };  /* if need DMA fixup */
 680             };  /* for loop to fill list */
 681 #ifdef DEBUG
 682             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 683                    this_count, 
 684                    SCpnt->request.current_nr_sectors,
 685                    SCpnt->request.nr_sectors);
 686             for(count=0; count<SCpnt->use_sg; count++)
 687               printk("SGlist: %d %x %x %x\n", count,
 688                      sgpnt[count].address, 
 689                      sgpnt[count].alt_address, 
 690                      sgpnt[count].length);
 691 #endif
 692           };  /* Able to allocate scatter-gather list */
 693         };
 694         
 695         if (SCpnt->use_sg == 0){
 696           /* We cannot use scatter-gather.  Do this the old fashion way */
 697           if (!SCpnt->request.bh)       
 698             this_count = SCpnt->request.nr_sectors;
 699           else
 700             this_count = (SCpnt->request.bh->b_size >> 9);
 701           
 702           start = block % 4;
 703           if (start)
 704             {                             
 705               this_count = ((this_count > 4 - start) ? 
 706                             (4 - start) : (this_count));
 707               buffer = (unsigned char *) scsi_malloc(2048);
 708             } 
 709           else if (this_count < 4)
 710             {
 711               buffer = (unsigned char *) scsi_malloc(2048);
 712             }
 713           else
 714             {
 715               this_count -= this_count % 4;
 716               buffer = (unsigned char *) SCpnt->request.buffer;
 717               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 718                   (SCpnt->host->unchecked_isa_dma))
 719                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 720             }
 721         };
 722 
 723         if (scsi_CDs[dev].sector_size == 2048)
 724           block = block >> 2; /* These are the sectors that the cdrom uses */
 725         else
 726           block = block & 0xfffffffc;
 727 
 728         realcount = (this_count + 3) / 4;
 729 
 730         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 731 
 732         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 733                 {
 734                 if (realcount > 0xffff)
 735                         {
 736                         realcount = 0xffff;
 737                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 738                         }
 739 
 740                 cmd[0] += READ_10 - READ_6 ;
 741                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 742                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 743                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 744                 cmd[5] = (unsigned char) block & 0xff;
 745                 cmd[6] = cmd[9] = 0;
 746                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 747                 cmd[8] = (unsigned char) realcount & 0xff;
 748                 }
 749         else
 750                 {
 751                   if (realcount > 0xff)
 752                     {
 753                       realcount = 0xff;
 754                       this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 755                     }
 756                   
 757                   cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 758                   cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 759                   cmd[3] = (unsigned char) block & 0xff;
 760                   cmd[4] = (unsigned char) realcount;
 761                   cmd[5] = 0;
 762                 }   
 763 
 764 #ifdef DEBUG
 765         { 
 766           int i;
 767           printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 768           printk("Use sg: %d\n", SCpnt->use_sg);
 769           printk("Dumping command: ");
 770           for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 771           printk("\n");
 772         };
 773 #endif
 774 
 775 /* Some dumb host adapters can speed transfers by knowing the
 776  * minimum transfersize in advance.
 777  *
 778  * We shouldn't disconnect in the middle of a sector, but the cdrom
 779  * sector size can be larger than the size of a buffer and the
 780  * transfer may be split to the size of a buffer.  So it's safe to
 781  * assume that we can at least transfer the minimum of the buffer
 782  * size (1024) and the sector size between each connect / disconnect.
 783  */
 784 
 785         SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
 786                         1024 : scsi_CDs[dev].sector_size;
 787 
 788         SCpnt->this_count = this_count;
 789         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 790                      realcount * scsi_CDs[dev].sector_size, 
 791                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 792 }
 793 
 794 static int sr_detect(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 795   
 796   /* We do not support attaching loadable devices yet. */
 797   if(scsi_loadable_module_flag) return 0;
 798   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
 799 
 800   printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", 
 801          sr_template.dev_noticed++,
 802          SDp->host->host_no , SDp->id, SDp->lun); 
 803 
 804          return 1;
 805 }
 806 
 807 static void sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 808   Scsi_CD * cpnt;
 809   int i;
 810   
 811   /* We do not support attaching loadable devices yet. */
 812   
 813   if(scsi_loadable_module_flag) return;
 814   if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return;
 815   
 816   if (sr_template.nr_dev >= sr_template.dev_max)
 817     panic ("scsi_devices corrupt (sr)");
 818   
 819   for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) 
 820     if(!cpnt->device) break;
 821   
 822   if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
 823   
 824   SDp->scsi_request_fn = do_sr_request;
 825   scsi_CDs[i].device = SDp;
 826   sr_template.nr_dev++;
 827   if(sr_template.nr_dev > sr_template.dev_max)
 828     panic ("scsi_devices corrupt (sr)");
 829 }
 830      
 831 
 832 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 833 {
 834   struct request * req;
 835   
 836   req = &SCpnt->request;
 837   req->dev = 0xfffe; /* Busy, but indicate request done */
 838   
 839   if (req->sem != NULL) {
 840     up(req->sem);
 841   }
 842 }
 843 
 844 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 845   unsigned char cmd[10];
 846   unsigned char *buffer;
 847   int the_result, retries;
 848   Scsi_Cmnd * SCpnt;
 849   
 850   buffer = (unsigned char *) scsi_malloc(512);
 851   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 852 
 853   retries = 3;
 854   do {
 855     cmd[0] = READ_CAPACITY;
 856     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 857     memset ((void *) &cmd[2], 0, 8);
 858     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 859     SCpnt->cmd_len = 0;
 860     
 861     memset(buffer, 0, 8);
 862 
 863     scsi_do_cmd (SCpnt,
 864                  (void *) cmd, (void *) buffer,
 865                  512, sr_init_done,  SR_TIMEOUT,
 866                  MAX_RETRIES);
 867     
 868     if (current == task[0])
 869       while(SCpnt->request.dev != 0xfffe);
 870     else
 871       if (SCpnt->request.dev != 0xfffe){
 872         struct semaphore sem = MUTEX_LOCKED;
 873         SCpnt->request.sem = &sem;
 874         down(&sem);
 875         /* Hmm.. Have to ask about this */
 876         while (SCpnt->request.dev != 0xfffe) schedule();
 877       };
 878     
 879     the_result = SCpnt->result;
 880     retries--;
 881     
 882   } while(the_result && retries);
 883   
 884   SCpnt->request.dev = -1;  /* Mark as not busy */
 885   
 886   wake_up(&SCpnt->device->device_wait); 
 887 
 888   if (the_result) {
 889     scsi_CDs[i].capacity = 0x1fffff;
 890     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 891     scsi_CDs[i].needs_sector_size = 1;
 892   } else {
 893     scsi_CDs[i].capacity = (buffer[0] << 24) |
 894       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 895     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 896       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 897     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 898     if(scsi_CDs[i].sector_size != 2048 && 
 899        scsi_CDs[i].sector_size != 512) {
 900       printk ("scd%d : unsupported sector size %d.\n",
 901               i, scsi_CDs[i].sector_size);
 902       scsi_CDs[i].capacity = 0;
 903       scsi_CDs[i].needs_sector_size = 1;
 904     };
 905     if(scsi_CDs[i].sector_size == 2048)
 906       scsi_CDs[i].capacity *= 4;
 907     scsi_CDs[i].needs_sector_size = 0;
 908   };
 909   scsi_free(buffer, 512);
 910 }
 911 
 912 static void sr_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914         int i;
 915         static int sr_registered = 0;
 916 
 917         if(sr_template.dev_noticed == 0) return;
 918 
 919         if(!sr_registered) {
 920           if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 921             printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 922             return;
 923           }
 924         }
 925 
 926         /* We do not support attaching loadable devices yet. */
 927         if(scsi_loadable_module_flag) return;
 928 
 929         sr_template.dev_max = sr_template.dev_noticed;
 930         scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD));
 931         memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
 932 
 933         sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int));
 934         memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
 935 
 936         sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 937                                                  sizeof(int));
 938         for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
 939         blksize_size[MAJOR_NR] = sr_blocksizes;
 940 
 941 }
 942 
 943 void sr_finish()
     /* [previous][next][first][last][top][bottom][index][help] */
 944 {
 945   int i;
 946 
 947         for (i = 0; i < sr_template.nr_dev; ++i)
 948                 {
 949                   get_sectorsize(i);
 950                   printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
 951                   scsi_CDs[i].use = 1;
 952                   scsi_CDs[i].ten = 1;
 953                   scsi_CDs[i].remap = 1;
 954                   sr_sizes[i] = scsi_CDs[i].capacity;
 955                 }
 956 
 957         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 958         blk_size[MAJOR_NR] = sr_sizes;  
 959 
 960         /* If our host adapter is capable of scatter-gather, then we increase
 961            the read-ahead to 16 blocks (32 sectors).  If not, we use
 962            a two block (4 sector) read ahead. */
 963         if(scsi_CDs[0].device->host->sg_tablesize)
 964           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 965         else
 966           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 967 
 968         return;
 969 }       

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