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

📄 sd.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * 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);#ifdef MACH	printk ("SCSI device sd%d: hdwr sector= %d bytes."               " Sectors= %d [%d MB] [%d.%1d GB]\n",		i, hard_sector, rscsi_disks[i].capacity,                 mb, sz_quot, sz_rem);#else	printk ("SCSI device sd%c: hdwr sector= %d bytes."               " Sectors= %d [%d MB] [%d.%1d GB]\n",		i+'a', hard_sector, rscsi_disks[i].capacity,                 mb, sz_quot, sz_rem);#endif    }	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);	    down(&sem);	}		the_result = SCpnt->result;	SCpnt->request.rq_status = RQ_INACTIVE;  /* Mark as not busy */	wake_up(&SCpnt->device->device_wait); 		if ( the_result ) {#ifdef MACH	    printk ("sd%d: test WP failed, assume Write Protected\n",i);#else	    printk ("sd%c: test WP failed, assume Write Protected\n",i+'a');#endif	    rscsi_disks[i].write_prot = 1;	} else {	    rscsi_disks[i].write_prot = ((buffer[2] & 0x80) != 0);#ifdef MACH	    printk ("sd%d: Write Protect is %s\n",i,	            rscsi_disks[i].write_prot ? "on" : "off");#else	    printk ("sd%c: Write Protect is %s\n",i+'a',	            rscsi_disks[i].write_prot ? "on" : "off");#endif	}	    }	/* check for write protect */     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. */static int sd_registered = 0;static int sd_init(){    int i;        if (sd_template.dev_noticed == 0) return 0;        if(!sd_registered) {	  if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) {	      printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);	      return 1;	  }	  sd_registered++;      }        /* We do not support attaching loadable devices yet. */    if(rscsi_disks) return 0;        sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;        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));        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;    }    blksize_size[MAJOR_NR] = sd_blocksizes;    hardsect_size[MAJOR_NR] = sd_hardsizes;    sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *					       sizeof(struct hd_struct),					       GFP_ATOMIC);            sd_gendisk.max_nr = sd_template.dev_max;    sd_gendisk.part = sd;    sd_gendisk.sizes = sd_sizes;    sd_gendisk.real_devices = (void *) rscsi_disks;    return 0;}static void sd_finish(void){    struct gendisk *gendisk;    int i;    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;        for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)      if (gendisk == &sd_gendisk)	break;    if (gendisk == NULL)      {	sd_gendisk.next = gendisk_head;	gendisk_head = &sd_gendisk;      }        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(MAJOR_NR, i << 4), 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 16 blocks (32 sectors).  If not, we use     * a two block (4 sector) read ahead.      */    if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)	read_ahead[MAJOR_NR] = 120;  /* 120 sector read-ahead */    else	read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */    return;}static int sd_detect(Scsi_Device * SDp){    if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;#ifdef MACH    printk("Detected scsi %sdisk sd%d at scsi%d, channel %d, id %d, lun %d\n",            SDp->removable ? "removable " : "",	   sd_template.dev_noticed++,	   SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);#else    printk("Detected scsi %sdisk sd%c at scsi%d, channel %d, id %d, lun %d\n",            SDp->removable ? "removable " : "",	   'a'+ (sd_template.dev_noticed++),	   SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);#endif        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.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)#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(kdev_t dev, int maxusage){    int target;    struct gendisk * gdev;    unsigned long flags;    int max_p;    int start;    int i;        target =  DEVICE_NR(dev);    gdev = &GENDISK_STRUCT;        save_flags(flags);    cli();    if (DEVICE_BUSY || USAGE > maxusage) {	restore_flags(flags);	printk("Device busy for revalidation (usage=%d)\n", USAGE);	return -EBUSY;    }    DEVICE_BUSY = 1;    restore_flags(flags);        max_p = gdev->max_p;    start = target << gdev->minor_shift;        for (i=max_p - 1; i >=0 ; i--) {	int minor = start+i;	kdev_t devi = MKDEV(MAJOR_NR, minor);	sync_dev(devi);	invalidate_inodes(devi);	invalidate_buffers(devi);	gdev->part[minor].start_sect = 0;	gdev->part[minor].nr_sects = 0;        /*         * Reset the blocksize for everything so that we can read         * the partition table.         */        blksize_size[MAJOR_NR][minor] = 1024;    }    #ifdef MAYBE_REINIT    MAYBE_REINIT;#endif        gdev->part[start].nr_sects = CAPACITY;    resetup_one_dev(gdev, target);        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;    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 (i=max_p - 1; i >=0 ; i--) {		int minor = start+i;		kdev_t devi = MKDEV(MAJOR_NR, minor);		sync_dev(devi);		invalidate_inodes(devi);		invalidate_buffers(devi);		sd_gendisk.part[minor].start_sect = 0;		sd_gendisk.part[minor].nr_sects = 0;		sd_sizes[minor] = 0;	    }	    	    dpnt->has_part_table = 0;	    dpnt->device = NULL;	    dpnt->capacity = 0;	    SDp->attached--;	    sd_template.dev_noticed--;	    sd_template.nr_dev--;	    sd_gendisk.nr_real--;	    return;	}    return;}#ifdef MODULEint init_module(void) {    sd_template.usage_count = &mod_use_count_;    return scsi_register_module(MODULE_SCSI_DEV, &sd_template);}void cleanup_module( void) {    struct gendisk * prev_sdgd;    struct gendisk * sdgd;        scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);    unregister_blkdev(SCSI_DISK_MAJOR, "sd");    sd_registered--;    if( rscsi_disks != NULL )    {	scsi_init_free((char *) rscsi_disks,		       (sd_template.dev_noticed + SD_EXTRA_DEVS) 		       * 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_gendisk from the linked list	 */	sdgd = gendisk_head;	prev_sdgd = NULL;	while(sdgd != &sd_gendisk)	{	    prev_sdgd = sdgd;	    sdgd = sdgd->next;	}		if(sdgd != &sd_gendisk)	    printk("sd_gendisk not in disk chain.\n");	else {	    if(prev_sdgd != NULL)		prev_sdgd->next = sdgd->next;	    else		gendisk_head = sdgd->next;	}    }        blksize_size[MAJOR_NR] = NULL;    blk_dev[MAJOR_NR].request_fn = NULL;    blk_size[MAJOR_NR] = NULL;      hardsect_size[MAJOR_NR] = NULL;    read_ahead[MAJOR_NR] = 0;    sd_template.dev_max = 0;}#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 + -