?? sd.c
字號:
SCpnt->use_sg = count; /* Number of chains */ count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/ while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) count = count << 1; SCpnt->sglist_len = count; sgpnt = (struct scatterlist * ) scsi_malloc(count); if (!sgpnt) { printk("Warning - running *really* short on DMA buffers\n"); SCpnt->use_sg = 0; /* No memory left - bail out */ this_count = SCpnt->request.current_nr_sectors; buff = SCpnt->request.buffer; } else { buff = (char *) sgpnt; count = 0; bh = SCpnt->request.bh; for(count = 0, bh = SCpnt->request.bh; count < SCpnt->use_sg; count++, bh = bh->b_reqnext) { sgpnt[count].address = bh->b_data; sgpnt[count].alt_address = NULL; sgpnt[count].length = bh->b_size; if (((int) sgpnt[count].address) + sgpnt[count].length > ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) { sgpnt[count].alt_address = sgpnt[count].address; /* We try and avoid exhausting the DMA pool, since it is easier to control usage here. In other places we might have a more pressing need, and we would be screwed if we ran out */ if(dma_free_sectors < (bh->b_size >> 9) + 5) { sgpnt[count].address = NULL; } else { sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length); };/* If we start running low on DMA buffers, we abort the scatter-gather operation, and free all of the memory we have allocated. We want to ensure that all scsi operations are able to do at least a non-scatter/gather operation */ if(sgpnt[count].address == NULL){ /* Out of dma memory */ printk("Warning: Running low on SCSI DMA buffers"); /* Try switching back to a non scatter-gather operation. */ while(--count >= 0){ if(sgpnt[count].alt_address) scsi_free(sgpnt[count].address, sgpnt[count].length); }; this_count = SCpnt->request.current_nr_sectors; buff = SCpnt->request.buffer; SCpnt->use_sg = 0; scsi_free(buff, SCpnt->sglist_len); break; }; if (SCpnt->request.cmd == WRITE) memcpy(sgpnt[count].address, sgpnt[count].alt_address, sgpnt[count].length); }; }; /* for loop */ }; /* 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 (((int) buff) + (this_count << 9) > ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma)) { buff = (char *) scsi_malloc(this_count << 9); if(buff == NULL) panic("Ran out of DMA buffers."); if (SCpnt->request.cmd == WRITE) memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9); }; };#ifdef DEBUG printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(SCpnt->request.dev), (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, SD_TIMEOUT, MAX_RETRIES);}int check_scsidisk_media_change(int full_dev, int flag){ int retval; int target; struct inode inode; target = DEVICE_NR(MINOR(full_dev)); if (target >= NR_SD) { 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 */ retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 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].device->changed = 1; return 1; /* This will force a flush, if called from check_disk_change */ }; 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; struct task_struct * p; req = &SCpnt->request; req->dev = 0xfffe; /* Busy, but indicate request done */ if ((p = req->waiting) != NULL) { req->waiting = NULL; p->state = TASK_RUNNING; if (p->counter > current->counter) need_resched = 1; }}static int sd_init_onedisk(int i){ int j = 0; unsigned char cmd[10]; unsigned char *buffer; char 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->index, 1); buffer = (unsigned char *) scsi_malloc(512); spintime = 0; /* Spin up drives, as required. Only do this at boot time */ if (current == task[0]){ do{ cmd[0] = TEST_UNIT_READY; cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; memset ((void *) &cmd[2], 0, 8); SCpnt->request.dev = 0xffff; /* Mark as really busy again */ SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); while(SCpnt->request.dev != 0xfffe); the_result = SCpnt->result; /* 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) { int time1; if(!spintime){ printk( "sd%d: Spinning up disk...", i ); 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->request.dev = 0xffff; /* Mark as really busy again */ SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); while(SCpnt->request.dev != 0xfffe); spintime = jiffies; }; time1 = jiffies; while(jiffies < time1 + 100); /* Wait 1 second for next try */ printk( "." ); }; } while(the_result && spintime && spintime+5000 > jiffies); if (spintime) { if (the_result) printk( "not responding...\n" ); else printk( "ready\n" ); } }; /* current == task[0] */ 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->request.dev = 0xffff; /* Mark as really busy again */ SCpnt->sense_buffer[0] = 0; SCpnt->sense_buffer[2] = 0; scsi_do_cmd (SCpnt, (void *) cmd, (void *) buffer, 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES); if (current == task[0]) while(SCpnt->request.dev != 0xfffe); else if (SCpnt->request.dev != 0xfffe){ SCpnt->request.waiting = current; current->state = TASK_UNINTERRUPTIBLE; while (SCpnt->request.dev != 0xfffe) schedule(); }; the_result = SCpnt->result; retries--; } while(the_result && retries); SCpnt->request.dev = -1; /* Mark as not busy */ wake_up(&scsi_devices[SCpnt->index].device_wait); /* Wake up a process waiting for device*/ /* * The SCSI standard says "READ CAPACITY is necessary for self confuring 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) { printk ("sd%d : READ CAPACITY failed.\n" "sd%d : status = %x, message = %02x, host = %d, driver = %02x \n", i,i, status_byte(the_result), msg_byte(the_result), host_byte(the_result), driver_byte(the_result) ); if (driver_byte(the_result) & DRIVER_SENSE) printk("sd%d : extended sense code = %1x \n", i, SCpnt->sense_buffer[2] & 0xf); else printk("sd%d : sense not available. \n", i); printk("sd%d : block size assumed to be 512 bytes, disk size 1GB. \n", i); 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 { rscsi_disks[i].capacity = (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 != 512 && rscsi_disks[i].sector_size != 1024 && rscsi_disks[i].sector_size != 256) { printk ("sd%d : unsupported sector size %d.\n", i, rscsi_disks[i].sector_size); if(rscsi_disks[i].device->removable){ rscsi_disks[i].capacity = 0; } else { printk ("scsi : deleting disk entry.\n"); for (j=i; j < NR_SD - 1;) rscsi_disks[j] = rscsi_disks[++j]; --i; --NR_SD; scsi_free(buffer, 512); return i; }; } if(rscsi_disks[i].sector_size == 1024) rscsi_disks[i].capacity <<= 1; /* Change this into 512 byte sectors */ if(rscsi_disks[i].sector_size == 256) rscsi_disks[i].capacity >>= 1; /* Change this into 512 byte sectors */ } rscsi_disks[i].ten = 1; rscsi_disks[i].remap = 1; scsi_free(buffer, 512); return i;}/* The sd_init() function looks at all SCSI drives present, determines their size, and reads partition table entries for them.*/unsigned long sd_init(unsigned long memory_start, unsigned long memory_end){ int i; if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) { printk("Unable to get major %d for SCSI disk\n",MAJOR_NR); return memory_start; } if (MAX_SD == 0) return memory_start; sd_sizes = (int *) memory_start; memory_start += (MAX_SD << 4) * sizeof(int); memset(sd_sizes, 0, (MAX_SD << 4) * sizeof(int)); sd_blocksizes = (int *) memory_start; memory_start += (MAX_SD << 4) * sizeof(int); for(i=0;i<(MAX_SD << 4);i++) sd_blocksizes[i] = 1024; blksize_size[MAJOR_NR] = sd_blocksizes; sd = (struct hd_struct *) memory_start; memory_start += (MAX_SD << 4) * sizeof(struct hd_struct); sd_gendisk.max_nr = MAX_SD; sd_gendisk.part = sd; sd_gendisk.sizes = sd_sizes; sd_gendisk.real_devices = (void *) rscsi_disks; for (i = 0; i < NR_SD; ++i) i = sd_init_onedisk(i); blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; /* If our host adapter is capable of scatter-gather, then we increase the read-ahead to 16 blocks (32 sectors). If not, we use a two block (4 sector) read ahead. */ if(rscsi_disks[0].device->host->sg_tablesize) read_ahead[MAJOR_NR] = 32; /* 64 sector read-ahead */ else read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */ sd_gendisk.next = gendisk_head; gendisk_head = &sd_gendisk; return memory_start;}unsigned long sd_init1(unsigned long mem_start, unsigned long mem_end){ rscsi_disks = (Scsi_Disk *) mem_start; mem_start += MAX_SD * sizeof(Scsi_Disk); return mem_start;};void sd_attach(Scsi_Device * SDp){ rscsi_disks[NR_SD++].device = SDp; if(NR_SD > MAX_SD) panic ("scsi_devices corrupt (sd)");};#define DEVICE_BUSY rscsi_disks[target].device->busy#define USAGE rscsi_disks[target].device->access_count#define CAPACITY rscsi_disks[target].capacity#define MAYBE_REINIT sd_init_onedisk(target)#define GENDISK_STRUCT sd_gendisk/* This routine is called to flush all partitions and partition tables for a changed scsi disk, and then re-read the new partition table. If we are revalidating a disk because of a media change, then we enter with usage == 0. If we are using an ioctl, we automatically have usage == 1 (we need an open channel to use an ioctl :-), so this is our limit. */int revalidate_scsidisk(int dev, int maxusage){ int target, major; struct gendisk * gdev; int max_p; int start; int i; target = DEVICE_NR(MINOR(dev)); gdev = &GENDISK_STRUCT; cli(); if (DEVICE_BUSY || USAGE > maxusage) { sti(); printk("Device busy for revalidation (usage=%d)\n", USAGE); return -EBUSY; }; DEVICE_BUSY = 1; sti(); max_p = gdev->max_p; start = target << gdev->minor_shift; major = MAJOR_NR << 8; for (i=max_p - 1; i >=0 ; i--) { sync_dev(major | start | i); invalidate_inodes(major | start | i); invalidate_buffers(major | start | i); gdev->part[start+i].start_sect = 0; gdev->part[start+i].nr_sects = 0; };#ifdef MAYBE_REINIT MAYBE_REINIT;#endif gdev->part[start].nr_sects = CAPACITY; resetup_one_dev(gdev, target); DEVICE_BUSY = 0; return 0;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -