⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
              }          }    {	/*	 * The msdos fs needs to know the hardware sector size	 * So I have created this table. See ll_rw_blk.c	 * Jacques Gelinas (Jacques@solucorp.qc.ca)	 */	int m, mb;        int sz_quot, sz_rem;	int hard_sector = rscsi_disks[i].sector_size;	/* There are 16 minors allocated for each major device */	for (m=i<<4; m<((i+1)<<4); m++){	    sd_hardsizes[m] = hard_sector;	}        mb = rscsi_disks[i].capacity / 1024 * hard_sector / 1024;        /* sz = div(m/100, 10);  this seems to not be in the libr */        m = (mb + 50) / 100;        sz_quot = m / 10;        sz_rem = m - (10 * sz_quot);	printk ("SCSI device %s: hdwr sector= %d bytes."               " Sectors= %d [%d MB] [%d.%1d GB]\n",		nbuff, hard_sector, rscsi_disks[i].capacity,                mb, sz_quot, sz_rem);    }	if(rscsi_disks[i].sector_size == 4096)	    rscsi_disks[i].capacity <<= 3;	if(rscsi_disks[i].sector_size == 2048)	    rscsi_disks[i].capacity <<= 2;  /* Change into 512 byte sectors */	if(rscsi_disks[i].sector_size == 1024)	    rscsi_disks[i].capacity <<= 1;  /* Change into 512 byte sectors */	if(rscsi_disks[i].sector_size == 256)	    rscsi_disks[i].capacity >>= 1;  /* Change into 512 byte sectors */    }    /*     * Unless otherwise specified, this is not write protected.     */    rscsi_disks[i].write_prot = 0;    if ( rscsi_disks[i].device->removable && rscsi_disks[i].ready ) {	/* FLOPTICAL */	/*	 *	for removable scsi disk ( FLOPTICAL ) we have to recognise	 * the Write Protect Flag. This flag is kept in the Scsi_Disk struct	 * and tested at open !	 * Daniel Roche ( dan@lectra.fr )	 */	memset ((void *) &cmd[0], 0, 8);	cmd[0] = MODE_SENSE;	cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;	cmd[2] = 1;	 /* page code 1 ?? */	cmd[4] = 12;	SCpnt->cmd_len = 0;	SCpnt->sense_buffer[0] = 0;	SCpnt->sense_buffer[2] = 0;	/* same code as READCAPA !! */	{	    struct semaphore sem = MUTEX_LOCKED;	    SCpnt->request.rq_status = RQ_SCSI_BUSY;  /* Mark as really busy again */	    SCpnt->request.sem = &sem;	    scsi_do_cmd (SCpnt,			 (void *) cmd, (void *) buffer,			 512, sd_init_done,  SD_TIMEOUT,			 MAX_RETRIES);	    spin_unlock_irq(&io_request_lock);	    down(&sem);	    spin_lock_irq(&io_request_lock);            SCpnt->request.sem = NULL;	}	the_result = SCpnt->result;	if ( the_result ) {	    printk ("%s: test WP failed, assume Write Protected\n",nbuff);	    rscsi_disks[i].write_prot = 1;	} else {	    rscsi_disks[i].write_prot = ((buffer[2] & 0x80) != 0);	    printk ("%s: Write Protect is %s\n",nbuff,	            rscsi_disks[i].write_prot ? "on" : "off");	}    }	/* check for write protect */    /* Wake up a process waiting for device */    wake_up(&SCpnt->device->device_wait);    scsi_release_command(SCpnt);    SCpnt = NULL;    rscsi_disks[i].ten = 1;    rscsi_disks[i].remap = 1;    scsi_free(buffer, 512);    spin_unlock_irq(&io_request_lock);    return i;}/* * The sd_init() function looks at all SCSI drives present, determines * their size, and reads partition table entries for them. */static int sd_registered = 0;static int sd_init(){    int i;    if (sd_template.dev_noticed == 0) return 0;    if (!rscsi_disks)        sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;    if(sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR )	sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;    if(!sd_registered) {	for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {	    if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) {		printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i));		return 1;	    }	}	sd_registered++;    }    /* We do not support attaching loadable devices yet. */    if(rscsi_disks) return 0;    rscsi_disks = (Scsi_Disk *)	scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);    memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));      /* for every (necessary) major: */    sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);    memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));    sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);    sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);    for(i=0; i < sd_template.dev_max << 4; i++) {	sd_blocksizes[i] = 1024;	sd_hardsizes[i] = 512;    }     for (i=0; i < N_USED_SD_MAJORS; i++) {	blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4);	hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4);    }    sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *					       sizeof(struct hd_struct),					       GFP_ATOMIC);    if (N_USED_SD_MAJORS > 1)    	sd_gendisks = (struct gendisk *)    	    kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);    for (i=0; i < N_USED_SD_MAJORS; i++) {	sd_gendisks[i].major = SD_MAJOR(i);	sd_gendisks[i].major_name = "sd";	sd_gendisks[i].minor_shift = 4;	sd_gendisks[i].max_p = 1 << 4;	sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR;	sd_gendisks[i].init = sd_geninit;	sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);	sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);	sd_gendisks[i].nr_real = 0;	sd_gendisks[i].next = sd_gendisks + i + 1;	sd_gendisks[i].real_devices =		 (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR);    }        LAST_SD_GENDISK.max_nr =    	(sd_template.dev_max -1 ) % SCSI_DISKS_PER_MAJOR + 1;    LAST_SD_GENDISK.next = NULL;    return 0;}/* * sd_get_queue() returns the queue which corresponds to a given device. */static struct request **sd_get_queue (kdev_t dev){	return &blk_dev[MAJOR_NR].current_request;}static void sd_finish(){    struct gendisk *gendisk;    int i;    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {        /* FIXME: After 2.2 we should implement multiple sd queues */        blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST;        if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue;    }    for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)      if (gendisk == sd_gendisks)	break;    if (gendisk == NULL)      {	LAST_SD_GENDISK.next = gendisk_head;	gendisk_head = sd_gendisks;      }    for (i = 0; i < sd_template.dev_max; ++i)	if (!rscsi_disks[i].capacity &&	    rscsi_disks[i].device)	{	    if (MODULE_FLAG		&& !rscsi_disks[i].has_part_table) {		sd_sizes[i << 4] = rscsi_disks[i].capacity;		/* revalidate does sd_init_onedisk via MAYBE_REINIT*/		revalidate_scsidisk(MKDEV_SD(i), 0);	    }	    else	    	i=sd_init_onedisk(i);	    rscsi_disks[i].has_part_table = 1;	}    /* If our host adapter is capable of scatter-gather, then we increase     * the read-ahead to 60 blocks (120 sectors).  If not, we use     * a two block (4 sector) read ahead. We can only respect this with the     * granularity of every 16 disks (one device major).     */    for (i=0; i < N_USED_SD_MAJORS; i++) {        read_ahead[SD_MAJOR(i)] =            (rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device          && rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device->host->sg_tablesize)            ? 120  /* 120 sector read-ahead */            : 4;   /* 4 sector read-ahead */    }    return;}static int sd_detect(Scsi_Device * SDp){    char nbuff[6];    if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;    sd_devname(sd_template.dev_noticed++, nbuff);    printk("Detected scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n",           SDp->removable ? "removable " : "",	   nbuff,	   SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);    return 1;}static int sd_attach(Scsi_Device * SDp){    Scsi_Disk * dpnt;    int i;    if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;    if(sd_template.nr_dev >= sd_template.dev_max) {	SDp->attached--;	return 1;    }    for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)	if(!dpnt->device) break;    if(i >= sd_template.dev_max) panic ("scsi_devices corrupt (sd)");    SDp->scsi_request_fn = do_sd_request;    rscsi_disks[i].device = SDp;    rscsi_disks[i].has_part_table = 0;    sd_template.nr_dev++;    SD_GENDISK(i).nr_real++;    return 0;}#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)/* 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(kdev_t dev, int maxusage) {    int target;    int max_p;    int start;    int i;    target =  DEVICE_NR(dev);    if (DEVICE_BUSY || USAGE > maxusage) {	printk("Device busy for revalidation (usage=%d)\n", USAGE);	return -EBUSY;    }    DEVICE_BUSY = 1;    max_p = sd_gendisks->max_p;    start = target << sd_gendisks->minor_shift;    for (i=max_p - 1; i >=0 ; i--) {	int index = start+i;	kdev_t devi = MKDEV_SD_PARTITION(index);        struct super_block *sb = get_super(devi);	sync_dev(devi);	if (sb) invalidate_inodes(sb);	invalidate_buffers(devi);	sd_gendisks->part[index].start_sect = 0;	sd_gendisks->part[index].nr_sects = 0;        /*         * Reset the blocksize for everything so that we can read         * the partition table.  Technically we will determine the         * correct block size when we revalidate, but we do this just         * to make sure that everything remains consistent.         */        sd_blocksizes[index] = 1024;        if( rscsi_disks[target].sector_size == 2048 )          sd_blocksizes[index] = 2048;        else          sd_blocksizes[index] = 1024;    }#ifdef MAYBE_REINIT    MAYBE_REINIT;#endif    sd_gendisks->part[start].nr_sects = CAPACITY;    resetup_one_dev(&SD_GENDISK(target),		    target % SCSI_DISKS_PER_MAJOR);    DEVICE_BUSY = 0;    return 0;}static int fop_revalidate_scsidisk(kdev_t dev){    return revalidate_scsidisk(dev, 0);}static void sd_detach(Scsi_Device * SDp){    Scsi_Disk * dpnt;    int i, j;    int max_p;    int start;    for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)	if(dpnt->device == SDp) {	    /* If we are disconnecting a disk driver, sync and invalidate	     * everything */	    max_p = sd_gendisk.max_p;	    start = i << sd_gendisk.minor_shift;	    for (j=max_p - 1; j >=0 ; j--) {		int index = start+j;		kdev_t devi = MKDEV_SD_PARTITION(index);                struct super_block *sb = get_super(devi);		sync_dev(devi);		if (sb) invalidate_inodes(sb);		invalidate_buffers(devi);		sd_gendisks->part[index].start_sect = 0;		sd_gendisks->part[index].nr_sects = 0;		sd_sizes[index] = 0;	    }	    dpnt->has_part_table = 0;	    dpnt->device = NULL;	    dpnt->capacity = 0;	    SDp->attached--;	    sd_template.dev_noticed--;	    sd_template.nr_dev--;	    SD_GENDISK(i).nr_real--;	    return;	}    return;}#ifdef MODULEint init_module(void) {    sd_template.module = &__this_module;    return scsi_register_module(MODULE_SCSI_DEV, &sd_template);}void cleanup_module( void){    struct gendisk ** prev_sdgd_link;    struct gendisk * sdgd;    int i;    int removed = 0;    scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) 	unregister_blkdev(SD_MAJOR(i),"sd");        sd_registered--;    if( rscsi_disks != NULL )    {	scsi_init_free((char *) rscsi_disks, 			sd_template.dev_max * sizeof(Scsi_Disk));	scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int));	scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int));	scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int));	scsi_init_free((char *) sd,		       (sd_template.dev_max << 4) * sizeof(struct hd_struct));	/*	 * Now remove sd_gendisks from the linked list	 */	prev_sdgd_link = &gendisk_head;	while ((sdgd = *prev_sdgd_link) != NULL) {	    if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) {		removed++;		*prev_sdgd_link = sdgd->next;		continue;	    }	    prev_sdgd_link = &sdgd->next;	}	if (removed != N_USED_SD_MAJORS)	    printk("%s %d sd_gendisks in disk chain",	    	removed > N_USED_SD_MAJORS ? "total" : "just", removed);	    }    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {        blk_dev[SD_MAJOR(i)].request_fn = NULL;        blk_size[SD_MAJOR(i)] = NULL;        hardsect_size[SD_MAJOR(i)] = NULL;        read_ahead[SD_MAJOR(i)] = 0;    }    sd_template.dev_max = 0;    if (sd_gendisks != &sd_gendisk) kfree(sd_gendisks);}#endif /* MODULE *//* * Overrides for Emacs so that we almost follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -