📄 sd.c
字号:
/* If we are allowed another sg chain, then increment * counter so we can insert it. Otherwise we will end up truncating */ if (SCpnt->use_sg < max_sg) SCpnt->use_sg++; } /* contiguous buffers */ } /* for loop */ /* This is actually how many we are going to transfer */ this_count = counted; if(count < SCpnt->use_sg || SCpnt->use_sg > SCpnt->host->sg_tablesize){ bh = SCpnt->request.bh; printk("Use sg, count %d %x %d\n", SCpnt->use_sg, count, dma_free_sectors); printk("maxsg = %x, counted = %d this_count = %d\n", max_sg, counted, this_count); while(bh){ printk("[%p %lx] ", bh->b_data, bh->b_size); bh = bh->b_reqnext; } if(SCpnt->use_sg < 16) for(count=0; count<SCpnt->use_sg; count++) printk("{%d:%p %p %d} ", count, sgpnt[count].address, sgpnt[count].alt_address, sgpnt[count].length); panic("Ooops"); } if (SCpnt->request.cmd == WRITE) for(count=0; count<SCpnt->use_sg; count++) if(sgpnt[count].alt_address) memcpy(sgpnt[count].address, sgpnt[count].alt_address, sgpnt[count].length); } /* Able to malloc sgpnt */ } /* Host adapter capable of scatter-gather */ /* Now handle the possibility of DMA to addresses > 16Mb */ if(SCpnt->use_sg == 0){ if (((long) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma)) { if(bounce_buffer) buff = bounce_buffer; else buff = (char *) scsi_malloc(this_count << 9); if(buff == NULL) { /* Try backing off a bit if we are low on mem*/ this_count = SCpnt->request.current_nr_sectors; buff = (char *) scsi_malloc(this_count << 9); if(!buff) panic("Ran out of DMA buffers."); } if (SCpnt->request.cmd == WRITE) memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9); } }#ifdef DEBUG printk("sd%c : %s %d/%d 512 byte blocks.\n", 'a' + devm, (SCpnt->request.cmd == WRITE) ? "writing" : "reading", this_count, SCpnt->request.nr_sectors);#endif cmd[1] = (SCpnt->lun << 5) & 0xe0; if (rscsi_disks[dev].sector_size == 1024){ if(block & 1) panic("sd.c:Bad block number requested"); if(this_count & 1) panic("sd.c:Bad block number requested"); block = block >> 1; this_count = this_count >> 1; } if (rscsi_disks[dev].sector_size == 256){ block = block << 1; this_count = this_count << 1; } if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten) { if (this_count > 0xffff) this_count = 0xffff; cmd[0] += READ_10 - READ_6 ; cmd[2] = (unsigned char) (block >> 24) & 0xff; cmd[3] = (unsigned char) (block >> 16) & 0xff; cmd[4] = (unsigned char) (block >> 8) & 0xff; cmd[5] = (unsigned char) block & 0xff; cmd[6] = cmd[9] = 0; cmd[7] = (unsigned char) (this_count >> 8) & 0xff; cmd[8] = (unsigned char) this_count & 0xff; } else { if (this_count > 0xff) this_count = 0xff; cmd[1] |= (unsigned char) ((block >> 16) & 0x1f); cmd[2] = (unsigned char) ((block >> 8) & 0xff); cmd[3] = (unsigned char) block & 0xff; cmd[4] = (unsigned char) this_count; cmd[5] = 0; } /* * We shouldn't disconnect in the middle of a sector, so with a dumb * host adapter, it's safe to assume that we can at least transfer * this many bytes between each connect / disconnect. */ SCpnt->transfersize = rscsi_disks[dev].sector_size; SCpnt->underflow = this_count << 9; scsi_do_cmd (SCpnt, (void *) cmd, buff, this_count * rscsi_disks[dev].sector_size, rw_intr, (SCpnt->device->type == TYPE_DISK ? SD_TIMEOUT : SD_MOD_TIMEOUT), MAX_RETRIES);}static int check_scsidisk_media_change(kdev_t full_dev){ int retval; int target; struct inode inode; int flag = 0; target = DEVICE_NR(full_dev); if (target >= sd_template.dev_max || !rscsi_disks[target].device) { printk("SCSI disk request error: invalid device.\n"); return 0; } if(!rscsi_disks[target].device->removable) return 0; inode.i_rdev = full_dev; /* This is all we really need here */ /* Using Start/Stop enables differentiation between drive with * no cartridge loaded - NOT READY, drive with changed cartridge - * UNIT ATTENTION, or with same cartridge - GOOD STATUS. * This also handles drives that auto spin down. eg iomega jaz 1GB * as this will spin up the drive. */ retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_START_UNIT, 0); if(retval){ /* Unable to test, unit probably not ready. This usually * means there is no disc in the drive. Mark as changed, * and we will figure it out later once the drive is * available again. */ rscsi_disks[target].ready = 0; rscsi_disks[target].device->changed = 1; return 1; /* This will force a flush, if called from * check_disk_change */ } /* * for removable scsi disk ( FLOPTICAL ) we have to recognise the * presence of disk in the drive. This is kept in the Scsi_Disk * struct and tested at open ! Daniel Roche ( dan@lectra.fr ) */ rscsi_disks[target].ready = 1; /* FLOPTICAL */ retval = rscsi_disks[target].device->changed; if(!flag) rscsi_disks[target].device->changed = 0; return retval;}static void sd_init_done (Scsi_Cmnd * SCpnt){ struct request * req; req = &SCpnt->request; req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ if (req->sem != NULL) { up(req->sem); }}static int sd_init_onedisk(int i){ unsigned char cmd[10]; unsigned char *buffer; unsigned long spintime; int the_result, retries; Scsi_Cmnd * SCpnt; /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is * considered a fatal error, and many devices report such an error * just after a scsi bus reset. */ SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1); buffer = (unsigned char *) scsi_malloc(512); spintime = 0; /* Spin up drives, as required. Only do this at boot time */ /* Spinup needs to be done for module loads too. */ do{ retries = 0; while(retries < 3) { cmd[0] = TEST_UNIT_READY; cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; { struct semaphore sem = MUTEX_LOCKED; /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); down(&sem); } the_result = SCpnt->result; retries++; if( the_result == 0 || SCpnt->sense_buffer[2] != UNIT_ATTENTION) break; } /* Look for non-removable devices that return NOT_READY. * Issue command to spin up drive for these cases. */ if(the_result && !rscsi_disks[i].device->removable && SCpnt->sense_buffer[2] == NOT_READY) { unsigned long time1; if(!spintime){#ifdef MACH printk( "sd%d: Spinning up disk...", i);#else printk( "sd%c: Spinning up disk...", 'a' + i );#endif cmd[0] = START_STOP; cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; cmd[1] |= 1; /* Return immediately */ memset ((void *) &cmd[2], 0, 8); cmd[4] = 1; /* Start spin cycle */ SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; { struct semaphore sem = MUTEX_LOCKED; /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); down(&sem); } spintime = jiffies; } time1 = jiffies + HZ; while(jiffies < time1); /* Wait 1 second for next try */ printk( "." ); } } while(the_result && spintime && spintime+100*HZ > jiffies); if (spintime) { if (the_result) printk( "not responding...\n" ); else printk( "ready\n" ); } retries = 3; do { cmd[0] = READ_CAPACITY; cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); memset ((void *) buffer, 0, 8); SCpnt->cmd_len = 0; SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; { struct semaphore sem = MUTEX_LOCKED; /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES); down(&sem); /* sleep until it is ready */ } the_result = SCpnt->result; retries--; } while(the_result && retries); SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ wake_up(&SCpnt->device->device_wait); /* Wake up a process waiting for device */ /* * The SCSI standard says: * "READ CAPACITY is necessary for self configuring software" * While not mandatory, support of READ CAPACITY is strongly encouraged. * We used to die if we couldn't successfully do a READ CAPACITY. * But, now we go on about our way. The side effects of this are * * 1. We can't know block size with certainty. I have said "512 bytes * is it" as this is most common. * * 2. Recovery from when some one attempts to read past the end of the * raw device will be slower. */ if (the_result) {#ifdef MACH printk ("sd%d : READ CAPACITY failed.\n" "sd%d : status = %x, message = %02x, host = %d, driver = %02x \n", i, i,#else printk ("sd%c : READ CAPACITY failed.\n" "sd%c : status = %x, message = %02x, host = %d, driver = %02x \n", 'a' + i, 'a' + i,#endif status_byte(the_result), msg_byte(the_result), host_byte(the_result), driver_byte(the_result) ); if (driver_byte(the_result) & DRIVER_SENSE)#ifdef MACH printk("sd%d : extended sense code = %1x \n", i, SCpnt->sense_buffer[2] & 0xf);#else printk("sd%c : extended sense code = %1x \n", 'a' + i, SCpnt->sense_buffer[2] & 0xf);#endif else#ifdef MACH printk("sd%d : sense not available. \n", i);#else printk("sd%c : sense not available. \n", 'a' + i);#endif#ifdef MACH printk("sd%d : block size assumed to be 512 bytes, disk size 1GB. \n", i);#else printk("sd%c : block size assumed to be 512 bytes, disk size 1GB. \n", 'a' + i);#endif rscsi_disks[i].capacity = 0x1fffff; rscsi_disks[i].sector_size = 512; /* Set dirty bit for removable devices if not ready - sometimes drives * will not report this properly. */ if(rscsi_disks[i].device->removable && SCpnt->sense_buffer[2] == NOT_READY) rscsi_disks[i].device->changed = 1; } else { /* * FLOPTICAL , if read_capa is ok , drive is assumed to be ready */ rscsi_disks[i].ready = 1; rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); rscsi_disks[i].sector_size = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; if (rscsi_disks[i].sector_size == 0) { rscsi_disks[i].sector_size = 512;#ifdef MACH printk("sd%d : sector size 0 reported, assuming 512.\n", i);#else printk("sd%c : sector size 0 reported, assuming 512.\n", 'a' + i);#endif } if (rscsi_disks[i].sector_size != 512 && rscsi_disks[i].sector_size != 1024 && rscsi_disks[i].sector_size != 256) {#ifdef MACH printk ("sd%d : unsupported sector size %d.\n", i, rscsi_disks[i].sector_size);#else printk ("sd%c : unsupported sector size %d.\n", 'a' + i, rscsi_disks[i].sector_size);#endif if(rscsi_disks[i].device->removable){ rscsi_disks[i].capacity = 0; } else { printk ("scsi : deleting disk entry.\n"); rscsi_disks[i].device = NULL; sd_template.nr_dev--; sd_gendisk.nr_real--; return i; } } { /* * The msdos fs needs to know the hardware sector size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -