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

📄 sd.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
			int hard_sector = sector_size;			int sz = rscsi_disks[i].capacity * (hard_sector/256);			/* There are 16 minors allocated for each major device */			for (m = i << 4; m < ((i + 1) << 4); m++) {				sd_hardsizes[m] = hard_sector;			}			printk("SCSI device %s: "			       "%d %d-byte hdwr sectors (%d MB)\n",			       nbuff, rscsi_disks[i].capacity,			       hard_sector, (sz/2 - sz/1250 + 974)/1950);		}		/* Rescale capacity to 512-byte units */		if (sector_size == 4096)			rscsi_disks[i].capacity <<= 3;		if (sector_size == 2048)			rscsi_disks[i].capacity <<= 2;		if (sector_size == 1024)			rscsi_disks[i].capacity <<= 1;		if (sector_size == 256)			rscsi_disks[i].capacity >>= 1;	}	/*	 * 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 )		 *		 * Changed to get all pages (0x3f) rather than page 1 to		 * get around devices which do not have a page 1.  Since		 * we're only interested in the header anyway, this should		 * be fine.		 *   -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)		 */		memset((void *) &cmd[0], 0, 8);		cmd[0] = MODE_SENSE;		cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;		cmd[2] = 0x3f;	/* Get all pages */		cmd[4] = 8;     /* But we only want the 8 byte header */		SRpnt->sr_cmd_len = 0;		SRpnt->sr_sense_buffer[0] = 0;		SRpnt->sr_sense_buffer[2] = 0;		/* same code as READCAPA !! */		SRpnt->sr_data_direction = SCSI_DATA_READ;		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,			    512, SD_TIMEOUT, MAX_RETRIES);		the_result = SRpnt->sr_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 */	SRpnt->sr_device->ten = 1;	SRpnt->sr_device->remap = 1;	SRpnt->sr_device->sector_size = sector_size;	/* Wake up a process waiting for device */	scsi_release_request(SRpnt);	SRpnt = NULL;	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;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 < N_USED_SD_MAJORS; i++) {			if (devfs_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 = kmalloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);	if (!rscsi_disks)		goto cleanup_devfs;	memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));	/* for every (necessary) major: */	sd_sizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);	if (!sd_sizes)		goto cleanup_disks;	memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));	sd_blocksizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);	if (!sd_blocksizes)		goto cleanup_sizes;		sd_hardsizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);	if (!sd_hardsizes)		goto cleanup_blocksizes;	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 = kmalloc((sd_template.dev_max << 4) *					  sizeof(struct hd_struct),					  GFP_ATOMIC);	if (!sd)		goto cleanup_sd;	memset(sd, 0, (sd_template.dev_max << 4) * sizeof(struct hd_struct));	if (N_USED_SD_MAJORS > 1)		sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);		if (!sd_gendisks)			goto cleanup_sd_gendisks;	for (i = 0; i < N_USED_SD_MAJORS; i++) {		sd_gendisks[i] = sd_gendisk;		sd_gendisks[i].de_arr = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr,                                                 GFP_ATOMIC);		if (!sd_gendisks[i].de_arr)			goto cleanup_gendisks_de_arr;                memset (sd_gendisks[i].de_arr, 0,                        SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr);		sd_gendisks[i].flags = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags,                                                GFP_ATOMIC);		if (!sd_gendisks[i].flags)			goto cleanup_gendisks_flags;                memset (sd_gendisks[i].flags, 0,                        SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags);		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].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.next = NULL;	return 0;cleanup_gendisks_flags:	kfree(sd_gendisks[i].de_arr);cleanup_gendisks_de_arr:	while (--i >= 0 ) {		kfree(sd_gendisks[i].de_arr);		kfree(sd_gendisks[i].flags);	}	kfree(sd_gendisks);cleanup_sd_gendisks:	kfree(sd);cleanup_sd:	kfree(sd_hardsizes);cleanup_blocksizes:	kfree(sd_blocksizes);cleanup_sizes:	kfree(sd_sizes);cleanup_disks:	kfree(rscsi_disks);cleanup_devfs:	for (i = 0; i < N_USED_SD_MAJORS; i++) {		devfs_unregister_blkdev(SD_MAJOR(i), "sd");	}	sd_registered--;	return 1;}static void sd_finish(){	struct gendisk *gendisk;	int i;	for (i = 0; i < N_USED_SD_MAJORS; i++) {		blk_dev[SD_MAJOR(i)].queue = sd_find_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) {			sd_init_onedisk(i);			if (!rscsi_disks[i].has_part_table) {				sd_sizes[i << 4] = rscsi_disks[i].capacity;				register_disk(&SD_GENDISK(i), MKDEV_SD(i),						1<<4, &sd_fops,						rscsi_disks[i].capacity);				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){        unsigned int devnum;	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)");	rscsi_disks[i].device = SDp;	rscsi_disks[i].has_part_table = 0;	sd_template.nr_dev++;	SD_GENDISK(i).nr_real++;        devnum = i % SCSI_DISKS_PER_MAJOR;        SD_GENDISK(i).de_arr[devnum] = SDp->de;        if (SDp->removable)		SD_GENDISK(i).flags[devnum] |= GENHD_FL_REMOVABLE;	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].device->sector_size == 2048)			sd_blocksizes[index] = 2048;		else			sd_blocksizes[index] = 1024;	}#ifdef MAYBE_REINIT	MAYBE_REINIT;#endif	grok_partitions(&SD_GENDISK(target), target % SCSI_DISKS_PER_MAJOR,			1<<4, CAPACITY);	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;			}                        devfs_register_partitions (&SD_GENDISK (i),                                                   SD_MINOR_NUMBER (start), 1);			/* unregister_disk() */			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;}static int __init init_sd(void){	sd_template.module = THIS_MODULE;	return scsi_register_module(MODULE_SCSI_DEV, &sd_template);}static void __exit exit_sd(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 < N_USED_SD_MAJORS; i++)		devfs_unregister_blkdev(SD_MAJOR(i), "sd");	sd_registered--;	if (rscsi_disks != NULL) {		kfree(rscsi_disks);		kfree(sd_sizes);		kfree(sd_blocksizes);		kfree(sd_hardsizes);		kfree((char *) sd);		/*		 * 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 < N_USED_SD_MAJORS; i++) {		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);}module_init(init_sd);module_exit(exit_sd);

⌨️ 快捷键说明

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