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_open
  5. do_sr_request
  6. requeue_sr_request
  7. sr_init1
  8. sr_attach
  9. sr_init_done
  10. get_sectorsize
  11. sr_init

   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 <asm/system.h>
  23 
  24 #define MAJOR_NR SCSI_CDROM_MAJOR
  25 #include "../block/blk.h"
  26 #include "scsi.h"
  27 #include "hosts.h"
  28 #include "sr.h"
  29 #include "scsi_ioctl.h"   /* For the door lock/unlock commands */
  30 #include "constants.h"
  31 
  32 #define MAX_RETRIES 1
  33 #define SR_TIMEOUT 500
  34 
  35 int NR_SR=0;
  36 int MAX_SR=0;
  37 Scsi_CD * scsi_CDs;
  38 static int * sr_sizes;
  39 
  40 static int * sr_blocksizes;
  41 
  42 static int sr_open(struct inode *, struct file *);
  43 static void get_sectorsize(int);
  44 
  45 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  46 
  47 void requeue_sr_request (Scsi_Cmnd * SCpnt);
  48 static int check_cdrom_media_change(dev_t);
  49 
  50 static void sr_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52         sync_dev(inode->i_rdev);
  53         if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
  54           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
  55 }
  56 
  57 static struct file_operations sr_fops = 
  58 {
  59         NULL,                   /* lseek - default */
  60         block_read,             /* read - general block-dev read */
  61         block_write,            /* write - general block-dev write */
  62         NULL,                   /* readdir - bad */
  63         NULL,                   /* select */
  64         sr_ioctl,               /* ioctl */
  65         NULL,                   /* mmap */
  66         sr_open,                /* special open code */
  67         sr_release,             /* release */
  68         NULL,                   /* fsync */
  69         NULL,                   /* fasync */
  70         check_cdrom_media_change,  /* Disk change */
  71         NULL                    /* revalidate */
  72 };
  73 
  74 /*
  75  * This function checks to see if the media has been changed in the
  76  * CDROM drive.  It is possible that we have already sensed a change,
  77  * or the drive may have sensed one and not yet reported it.  We must
  78  * be ready for either case. This function always reports the current
  79  * value of the changed bit.  If flag is 0, then the changed bit is reset.
  80  * This function could be done as an ioctl, but we would need to have
  81  * an inode for that to work, and we do not always have one.
  82  */
  83 
  84 int check_cdrom_media_change(dev_t full_dev){
     /* [previous][next][first][last][top][bottom][index][help] */
  85         int retval, target;
  86         struct inode inode;
  87         int flag = 0;
  88 
  89         target =  MINOR(full_dev);
  90 
  91         if (target >= NR_SR) {
  92                 printk("CD-ROM request error: invalid device.\n");
  93                 return 0;
  94         };
  95 
  96         inode.i_rdev = full_dev;  /* This is all we really need here */
  97         retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
  98 
  99         if(retval){ /* Unable to test, unit probably not ready.  This usually
 100                      means there is no disc in the drive.  Mark as changed,
 101                      and we will figure it out later once the drive is
 102                      available again.  */
 103 
 104           scsi_CDs[target].device->changed = 1;
 105           return 1; /* This will force a flush, if called from
 106                        check_disk_change */
 107         };
 108 
 109         retval = scsi_CDs[target].device->changed;
 110         if(!flag) {
 111           scsi_CDs[target].device->changed = 0;
 112           /* If the disk changed, the capacity will now be different,
 113              so we force a re-read of this information */
 114           if (retval) scsi_CDs[target].needs_sector_size = 1;
 115         };
 116         return retval;
 117 }
 118 
 119 /*
 120  * rw_intr is the interrupt routine for the device driver.  It will be notified on the 
 121  * end of a SCSI read / write, and will take on of several actions based on success or failure.
 122  */
 123 
 124 static void rw_intr (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         int result = SCpnt->result;
 127         int this_count = SCpnt->this_count;
 128 
 129 #ifdef DEBUG
 130         printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
 131 #endif
 132         if (!result)
 133                 { /* No error */
 134                   if (SCpnt->use_sg == 0) {
 135                     if (SCpnt->buffer != SCpnt->request.buffer)
 136                       {
 137                         int offset;
 138                         offset = (SCpnt->request.sector % 4) << 9;
 139                         memcpy((char *)SCpnt->request.buffer, 
 140                                (char *)SCpnt->buffer + offset, 
 141                                this_count << 9);
 142                         /* Even though we are not using scatter-gather, we look
 143                            ahead and see if there is a linked request for the
 144                            other half of this buffer.  If there is, then satisfy
 145                            it. */
 146                         if((offset == 0) && this_count == 2 &&
 147                            SCpnt->request.nr_sectors > this_count && 
 148                            SCpnt->request.bh &&
 149                            SCpnt->request.bh->b_reqnext &&
 150                            SCpnt->request.bh->b_reqnext->b_size == 1024) {
 151                           memcpy((char *)SCpnt->request.bh->b_reqnext->b_data, 
 152                                  (char *)SCpnt->buffer + 1024, 
 153                                  1024);
 154                           this_count += 2;
 155                         };
 156                         
 157                         scsi_free(SCpnt->buffer, 2048);
 158                       }
 159                   } else {
 160                     struct scatterlist * sgpnt;
 161                     int i;
 162                     sgpnt = (struct scatterlist *) SCpnt->buffer;
 163                     for(i=0; i<SCpnt->use_sg; i++) {
 164                       if (sgpnt[i].alt_address) {
 165                         if (sgpnt[i].alt_address != sgpnt[i].address) {
 166                           memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
 167                         };
 168                         scsi_free(sgpnt[i].address, sgpnt[i].length);
 169                       };
 170                     };
 171                     scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 172                     if(SCpnt->request.sector % 4) this_count -= 2;
 173 /* See   if there is a padding record at the end that needs to be removed */
 174                     if(this_count > SCpnt->request.nr_sectors)
 175                       this_count -= 2;
 176                   };
 177 
 178 #ifdef DEBUG
 179                 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors, 
 180                        this_count);
 181 #endif
 182                 if (SCpnt->request.nr_sectors > this_count)
 183                         {        
 184                         SCpnt->request.errors = 0;
 185                         if (!SCpnt->request.bh)
 186                             panic("sr.c: linked page request (%lx %x)",
 187                                   SCpnt->request.sector, this_count);
 188                         }
 189 
 190                   end_scsi_request(SCpnt, 1, this_count);  /* All done */
 191                   requeue_sr_request(SCpnt);
 192                   return;
 193                 } /* Normal completion */
 194 
 195         /* We only come through here if we have an error of some kind */
 196 
 197 /* Free up any indirection buffers we allocated for DMA purposes. */
 198         if (SCpnt->use_sg) {
 199           struct scatterlist * sgpnt;
 200           int i;
 201           sgpnt = (struct scatterlist *) SCpnt->buffer;
 202           for(i=0; i<SCpnt->use_sg; i++) {
 203             if (sgpnt[i].alt_address) {
 204               scsi_free(sgpnt[i].address, sgpnt[i].length);
 205             };
 206           };
 207           scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
 208         } else {
 209           if (SCpnt->buffer != SCpnt->request.buffer)
 210             scsi_free(SCpnt->buffer, SCpnt->bufflen);
 211         };
 212 
 213         if (driver_byte(result) != 0) {
 214                 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
 215                         if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
 216                                 /* detected disc change.  set a bit and quietly refuse  */
 217                                 /* further access.                                      */
 218                     
 219                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
 220                                 end_scsi_request(SCpnt, 0, this_count);
 221                                 requeue_sr_request(SCpnt);
 222                                 return;
 223                         }
 224                 }
 225             
 226                 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
 227                         printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
 228                         if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
 229                                 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
 230                                 requeue_sr_request(SCpnt);
 231                                 result = 0;
 232                                 return;
 233                         } else {
 234                           printk("CD-ROM error: Drive reports %d.\n", SCpnt->sense_buffer[2]);                          
 235                           end_scsi_request(SCpnt, 0, this_count);
 236                           requeue_sr_request(SCpnt); /* Do next request */
 237                           return;
 238                         }
 239 
 240                 }
 241 
 242                 if (SCpnt->sense_buffer[2] == NOT_READY) {
 243                         printk("CDROM not ready.  Make sure you have a disc in the drive.\n");
 244                         end_scsi_request(SCpnt, 0, this_count);
 245                         requeue_sr_request(SCpnt); /* Do next request */
 246                         return;
 247                 };
 248               }
 249         
 250         /* We only get this far if we have an error we have not recognized */
 251         if(result) {
 252           printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", 
 253                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host->host_no, 
 254                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
 255                  scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
 256                  result);
 257             
 258           if (status_byte(result) == CHECK_CONDITION)
 259                   print_sense("sr", SCpnt);
 260           
 261           end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
 262           requeue_sr_request(SCpnt);
 263   }
 264 }
 265 
 266 static int sr_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 267 {
 268         if(MINOR(inode->i_rdev) >= NR_SR || 
 269            !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;   /* No such device */
 270 
 271         check_disk_change(inode->i_rdev);
 272 
 273         if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
 274           sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
 275 
 276         /* If this device did not have media in the drive at boot time, then
 277            we would have been unable to get the sector size.  Check to see if
 278            this is the case, and try again.
 279            */
 280 
 281         if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
 282           get_sectorsize(MINOR(inode->i_rdev));
 283 
 284         return 0;
 285 }
 286 
 287 
 288 /*
 289  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
 290  * is to take block device requests, and translate them to SCSI commands.
 291  */
 292         
 293 static void do_sr_request (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295   Scsi_Cmnd * SCpnt = NULL;
 296   struct request * req = NULL;
 297   int flag = 0;
 298 
 299   while (1==1){
 300     cli();
 301     if (CURRENT != NULL && CURRENT->dev == -1) {
 302       sti();
 303       return;
 304     };
 305 
 306     INIT_SCSI_REQUEST;
 307 
 308     if (flag++ == 0)
 309       SCpnt = allocate_device(&CURRENT,
 310                               scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
 311     else SCpnt = NULL;
 312     sti();
 313 
 314 /* This is a performance enhancement.  We dig down into the request list and
 315    try and find a queueable request (i.e. device not busy, and host able to
 316    accept another command.  If we find one, then we queue it. This can
 317    make a big difference on systems with more than one disk drive.  We want
 318    to have the interrupts off when monkeying with the request list, because
 319    otherwise the kernel might try and slip in a request inbetween somewhere. */
 320 
 321     if (!SCpnt && NR_SR > 1){
 322       struct request *req1;
 323       req1 = NULL;
 324       cli();
 325       req = CURRENT;
 326       while(req){
 327         SCpnt = request_queueable(req,
 328                                   scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
 329         if(SCpnt) break;
 330         req1 = req;
 331         req = req->next;
 332       };
 333       if (SCpnt && req->dev == -1) {
 334         if (req == CURRENT) 
 335           CURRENT = CURRENT->next;
 336         else
 337           req1->next = req->next;
 338       };
 339       sti();
 340     };
 341     
 342     if (!SCpnt)
 343       return; /* Could not find anything to do */
 344     
 345   wake_up(&wait_for_request);
 346 
 347 /* Queue command */
 348   requeue_sr_request(SCpnt);
 349   };  /* While */
 350 }    
 351 
 352 void requeue_sr_request (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354         unsigned int dev, block, realcount;
 355         unsigned char cmd[10], *buffer, tries;
 356         int this_count, start, end_rec;
 357 
 358         tries = 2;
 359 
 360       repeat:
 361         if(SCpnt->request.dev <= 0) {
 362           do_sr_request();
 363           return;
 364         }
 365 
 366         dev =  MINOR(SCpnt->request.dev);
 367         block = SCpnt->request.sector;  
 368         buffer = NULL;
 369         this_count = 0;
 370 
 371         if (dev >= NR_SR)
 372                 {
 373                 /* printk("CD-ROM request error: invalid device.\n");                   */
 374                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 375                 tries = 2;
 376                 goto repeat;
 377                 }
 378 
 379         if (!scsi_CDs[dev].use)
 380                 {
 381                 /* printk("CD-ROM request error: device marked not in use.\n");         */
 382                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 383                 tries = 2;
 384                 goto repeat;
 385                 }
 386 
 387         if (scsi_CDs[dev].device->changed)
 388                 {
 389 /* 
 390  * quietly refuse to do anything to a changed disc until the changed bit has been reset
 391  */
 392                 /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
 393                 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 394                 tries = 2;
 395                 goto repeat;
 396                 }
 397         
 398         switch (SCpnt->request.cmd)
 399                 {
 400                 case WRITE:             
 401                         end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
 402                         goto repeat;
 403                         break;
 404                 case READ : 
 405                         cmd[0] = READ_6;
 406                         break;
 407                 default : 
 408                         panic ("Unknown sr command %d\n", SCpnt->request.cmd);
 409                 }
 410         
 411         cmd[1] = (SCpnt->lun << 5) & 0xe0;
 412 
 413 /*
 414            Now do the grungy work of figuring out which sectors we need, and
 415            where in memory we are going to put them.
 416 
 417            The variables we need are:
 418 
 419            this_count= number of 512 byte sectors being read 
 420            block     = starting cdrom sector to read.
 421            realcount = # of cdrom sectors to read
 422 
 423            The major difference between a scsi disk and a scsi cdrom
 424 is that we will always use scatter-gather if we can, because we can
 425 work around the fact that the buffer cache has a block size of 1024,
 426 and we have 2048 byte sectors.  This code should work for buffers that
 427 are any multiple of 512 bytes long.  */
 428 
 429         SCpnt->use_sg = 0;
 430 
 431         if (SCpnt->host->sg_tablesize > 0 &&
 432             (!need_isa_buffer ||
 433             dma_free_sectors >= 10)) {
 434           struct buffer_head * bh;
 435           struct scatterlist * sgpnt;
 436           int count, this_count_max;
 437           bh = SCpnt->request.bh;
 438           this_count = 0;
 439           count = 0;
 440           this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
 441           /* Calculate how many links we can use.  First see if we need
 442            a padding record at the start */
 443           this_count = SCpnt->request.sector % 4;
 444           if(this_count) count++;
 445           while(bh && count < SCpnt->host->sg_tablesize) {
 446             if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 447             this_count += (bh->b_size >> 9);
 448             count++;
 449             bh = bh->b_reqnext;
 450           };
 451           /* Fix up in case of an odd record at the end */
 452           end_rec = 0;
 453           if(this_count % 4) {
 454             if (count < SCpnt->host->sg_tablesize) {
 455               count++;
 456               end_rec = (4 - (this_count % 4)) << 9;
 457               this_count += 4 - (this_count % 4);
 458             } else {
 459               count--;
 460               this_count -= (this_count % 4);
 461             };
 462           };
 463           SCpnt->use_sg = count;  /* Number of chains */
 464           count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
 465           while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 466             count = count << 1;
 467           SCpnt->sglist_len = count;
 468           sgpnt = (struct scatterlist * ) scsi_malloc(count);
 469           if (!sgpnt) {
 470             printk("Warning - running *really* short on DMA buffers\n");
 471             SCpnt->use_sg = 0;  /* No memory left - bail out */
 472           } else {
 473             buffer = (unsigned char *) sgpnt;
 474             count = 0;
 475             bh = SCpnt->request.bh;
 476             if(SCpnt->request.sector % 4) {
 477               sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
 478               sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 479               if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 480               sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
 481                                                                   if needed */
 482               count++;
 483             };
 484             for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 
 485                 count++, bh = bh->b_reqnext) {
 486               if (bh) { /* Need a placeholder at the end of the record? */
 487                 sgpnt[count].address = bh->b_data;
 488                 sgpnt[count].length = bh->b_size;
 489                 sgpnt[count].alt_address = NULL;
 490               } else {
 491                 sgpnt[count].address = (char *) scsi_malloc(end_rec);
 492                 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
 493                 sgpnt[count].length = end_rec;
 494                 sgpnt[count].alt_address = sgpnt[count].address;
 495                 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
 496                 break;
 497               };
 498               if (((int) sgpnt[count].address) + sgpnt[count].length > 
 499                   ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
 500                 sgpnt[count].alt_address = sgpnt[count].address;
 501                 /* We try and avoid exhausting the DMA pool, since it is easier
 502                    to control usage here.  In other places we might have a more
 503                    pressing need, and we would be screwed if we ran out */
 504                 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
 505                   sgpnt[count].address = NULL;
 506                 } else {
 507                   sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
 508                 };
 509 /* If we start running low on DMA buffers, we abort the scatter-gather
 510    operation, and free all of the memory we have allocated.  We want to
 511    ensure that all scsi operations are able to do at least a non-scatter/gather
 512    operation */
 513                 if(sgpnt[count].address == NULL){ /* Out of dma memory */
 514                   printk("Warning: Running low on SCSI DMA buffers");
 515                   /* Try switching back to a non scatter-gather operation. */
 516                   while(--count >= 0){
 517                     if(sgpnt[count].alt_address) 
 518                       scsi_free(sgpnt[count].address, sgpnt[count].length);
 519                   };
 520                   SCpnt->use_sg = 0;
 521                   scsi_free(buffer, SCpnt->sglist_len);
 522                   break;
 523                 }; /* if address == NULL */
 524               };  /* if need DMA fixup */
 525             };  /* for loop to fill list */
 526 #ifdef DEBUG
 527             printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
 528                    this_count, 
 529                    SCpnt->request.current_nr_sectors,
 530                    SCpnt->request.nr_sectors);
 531             for(count=0; count<SCpnt->use_sg; count++)
 532               printk("SGlist: %d %x %x %x\n", count,
 533                      sgpnt[count].address, 
 534                      sgpnt[count].alt_address, 
 535                      sgpnt[count].length);
 536 #endif
 537           };  /* Able to allocate scatter-gather list */
 538         };
 539         
 540         if (SCpnt->use_sg == 0){
 541           /* We cannot use scatter-gather.  Do this the old fashion way */
 542           if (!SCpnt->request.bh)       
 543             this_count = SCpnt->request.nr_sectors;
 544           else
 545             this_count = (SCpnt->request.bh->b_size >> 9);
 546           
 547           start = block % 4;
 548           if (start)
 549             {                             
 550               this_count = ((this_count > 4 - start) ? 
 551                             (4 - start) : (this_count));
 552               buffer = (unsigned char *) scsi_malloc(2048);
 553             } 
 554           else if (this_count < 4)
 555             {
 556               buffer = (unsigned char *) scsi_malloc(2048);
 557             }
 558           else
 559             {
 560               this_count -= this_count % 4;
 561               buffer = (unsigned char *) SCpnt->request.buffer;
 562               if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 
 563                   (SCpnt->host->unchecked_isa_dma))
 564                 buffer = (unsigned char *) scsi_malloc(this_count << 9);
 565             }
 566         };
 567 
 568         if (scsi_CDs[dev].sector_size == 2048)
 569           block = block >> 2; /* These are the sectors that the cdrom uses */
 570         else
 571           block = block & 0xfffffffc;
 572 
 573         realcount = (this_count + 3) / 4;
 574 
 575         if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
 576 
 577         if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
 578                 {
 579                 if (realcount > 0xffff)
 580                         {
 581                         realcount = 0xffff;
 582                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 583                         }
 584 
 585                 cmd[0] += READ_10 - READ_6 ;
 586                 cmd[2] = (unsigned char) (block >> 24) & 0xff;
 587                 cmd[3] = (unsigned char) (block >> 16) & 0xff;
 588                 cmd[4] = (unsigned char) (block >> 8) & 0xff;
 589                 cmd[5] = (unsigned char) block & 0xff;
 590                 cmd[6] = cmd[9] = 0;
 591                 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
 592                 cmd[8] = (unsigned char) realcount & 0xff;
 593                 }
 594         else
 595                 {
 596                 if (realcount > 0xff)
 597                         {
 598                         realcount = 0xff;
 599                         this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
 600                         }
 601         
 602                 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 603                 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
 604                 cmd[3] = (unsigned char) block & 0xff;
 605                 cmd[4] = (unsigned char) realcount;
 606                 cmd[5] = 0;
 607                 }   
 608 
 609 #ifdef DEBUG
 610 { 
 611         int i;
 612         printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
 613         printk("Use sg: %d\n", SCpnt->use_sg);
 614         printk("Dumping command: ");
 615         for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
 616         printk("\n");
 617 };
 618 #endif
 619 
 620         SCpnt->this_count = this_count;
 621         scsi_do_cmd (SCpnt, (void *) cmd, buffer, 
 622                      realcount * scsi_CDs[dev].sector_size, 
 623                      rw_intr, SR_TIMEOUT, MAX_RETRIES);
 624 }
 625 
 626 void sr_init1(){
     /* [previous][next][first][last][top][bottom][index][help] */
 627   scsi_CDs = (Scsi_CD *) scsi_init_malloc(MAX_SR * sizeof(Scsi_CD));
 628 };
 629 
 630 void sr_attach(Scsi_Device * SDp){
     /* [previous][next][first][last][top][bottom][index][help] */
 631   SDp->scsi_request_fn = do_sr_request;
 632   scsi_CDs[NR_SR++].device = SDp;
 633   if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
 634 };
 635 
 636 static void sr_init_done (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 637 {
 638   struct request * req;
 639   struct task_struct * p;
 640   
 641   req = &SCpnt->request;
 642   req->dev = 0xfffe; /* Busy, but indicate request done */
 643   
 644   if ((p = req->waiting) != NULL) {
 645     req->waiting = NULL;
 646     p->state = TASK_RUNNING;
 647     if (p->counter > current->counter)
 648       need_resched = 1;
 649   }
 650 }
 651 
 652 static void get_sectorsize(int i){
     /* [previous][next][first][last][top][bottom][index][help] */
 653   unsigned char cmd[10];
 654   unsigned char buffer[513];
 655   int the_result, retries;
 656   Scsi_Cmnd * SCpnt;
 657   
 658   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 659 
 660   retries = 3;
 661   do {
 662     cmd[0] = READ_CAPACITY;
 663     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 664     memset ((void *) &cmd[2], 0, 8);
 665     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
 666     
 667     memset(buffer, 0, 8);
 668 
 669     scsi_do_cmd (SCpnt,
 670                  (void *) cmd, (void *) buffer,
 671                  512, sr_init_done,  SR_TIMEOUT,
 672                  MAX_RETRIES);
 673     
 674     if (current == task[0])
 675       while(SCpnt->request.dev != 0xfffe);
 676     else
 677       if (SCpnt->request.dev != 0xfffe){
 678         SCpnt->request.waiting = current;
 679         current->state = TASK_UNINTERRUPTIBLE;
 680         while (SCpnt->request.dev != 0xfffe) schedule();
 681       };
 682     
 683     the_result = SCpnt->result;
 684     retries--;
 685     
 686   } while(the_result && retries);
 687   
 688   SCpnt->request.dev = -1;  /* Mark as not busy */
 689   
 690   wake_up(&SCpnt->device->device_wait); 
 691 
 692   if (the_result) {
 693     scsi_CDs[i].capacity = 0x1fffff;
 694     scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */
 695     scsi_CDs[i].needs_sector_size = 1;
 696   } else {
 697     scsi_CDs[i].capacity = (buffer[0] << 24) |
 698       (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 699     scsi_CDs[i].sector_size = (buffer[4] << 24) |
 700       (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
 701     if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 702     if(scsi_CDs[i].sector_size != 2048 && 
 703        scsi_CDs[i].sector_size != 512) {
 704       printk ("scd%d : unsupported sector size %d.\n",
 705               i, scsi_CDs[i].sector_size);
 706       scsi_CDs[i].capacity = 0;
 707       scsi_CDs[i].needs_sector_size = 1;
 708     };
 709     if(scsi_CDs[i].sector_size == 2048)
 710       scsi_CDs[i].capacity *= 4;
 711     scsi_CDs[i].needs_sector_size = 0;
 712   };
 713 }
 714 
 715 unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 716 {
 717         int i;
 718 
 719         if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
 720                 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
 721                 return memory_start;
 722         }
 723         if(MAX_SR == 0) return memory_start;
 724 
 725         sr_sizes = (int *) memory_start;
 726         memory_start += MAX_SR * sizeof(int);
 727         memset(sr_sizes, 0, MAX_SR * sizeof(int));
 728 
 729         sr_blocksizes = (int *) memory_start;
 730         memory_start += MAX_SR * sizeof(int);
 731         for(i=0;i<MAX_SR;i++) sr_blocksizes[i] = 2048;
 732         blksize_size[MAJOR_NR] = sr_blocksizes;
 733 
 734         for (i = 0; i < NR_SR; ++i)
 735                 {
 736                   get_sectorsize(i);
 737                   printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
 738                   scsi_CDs[i].use = 1;
 739                   scsi_CDs[i].ten = 1;
 740                   scsi_CDs[i].remap = 1;
 741                   sr_sizes[i] = scsi_CDs[i].capacity;
 742                 }
 743 
 744         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
 745         blk_size[MAJOR_NR] = sr_sizes;  
 746 
 747         /* If our host adapter is capable of scatter-gather, then we increase
 748            the read-ahead to 16 blocks (32 sectors).  If not, we use
 749            a two block (4 sector) read ahead. */
 750         if(scsi_CDs[0].device->host->sg_tablesize)
 751           read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */
 752         else
 753           read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 754 
 755         return memory_start;
 756 }       

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