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

📄 dasd.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
			return;		}		asm volatile ("STCK %0":"=m" (cqr->stopclk));		if ( ( stat->cstat == 0x00 &&                        stat->dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END) ) ||                      dasd_erp_examine ( cqr ) == dasd_era_none ) {                  dasd_debug (0xc4c89692);	/* DHok */                  if (atomic_compare_and_swap (CQR_STATUS_IN_IO,						     CQR_STATUS_DONE,						     &cqr->status)) {				PRINT_WARN ("handler: cqrstat changed%d\n",					    atomic_read (&cqr->status));				atomic_set(&cqr->status, CQR_STATUS_DONE);			}			if ( ! ( dasd_info[cqr->devindex]-> flags &				DASD_INFO_FLAGS_INITIALIZED ) ) {				int rc = register_dasd_last ( cqr->devindex );				dasd_info[cqr->devindex]-> flags |=				DASD_INFO_FLAGS_INITIALIZED;				if ( rc ) {					dasd_info[cqr->devindex]->flags &= 					~DASD_INFO_FLAGS_NOT_FORMATTED;				} else {					dasd_info[cqr->devindex]->flags |= 					DASD_INFO_FLAGS_NOT_FORMATTED;				}			}			if (cqr->next) {                                dasd_debug (0xc4c8e2e3);	/* DHST */				if (dasd_start_IO (cqr->next) == 0) {					done_fast_io = 1;                                 } else {                                        atomic_inc (&chanq_tasks);				}			} 			break;		}                 /* only visited in case of error ! */		dasd_debug (0xc4c8c5d9);	/* DHER */		if (!cqr->dstat)			cqr->dstat = kmalloc (sizeof (devstat_t),					      GFP_ATOMIC);		if (cqr->dstat) {			memcpy (cqr->dstat, stat, sizeof (devstat_t));		} else {			PRINT_ERR ("no memory for dstat\n");		}		/* errorprocessing */		atomic_set (&cqr->status, CQR_STATUS_ERROR);                atomic_inc (&dasd_info[cqr->devindex]->queue.dirty_requests);        }        if (done_fast_io == 0)		atomic_clear_mask (DASD_CHANQ_BUSY,				   &dasd_info[cqr->devindex]->queue.flags);        	if (cqr->flags & DASD_DO_IO_SLEEP) {		dasd_debug (0xc4c8a6a4);	/* DHwu */		dasd_wakeup ();	} else if (! (cqr->options & DOIO_WAIT_FOR_INTERRUPT) ){                dasd_debug (0xc4c8a293);	/* DHsl */                atomic_inc (&chanq_tasks);                schedule_bh (dasd_do_chanq);	} else {                dasd_debug (0x64686f6f);	/* DH_g */                dasd_debug (cqr->flags);	/* DH_g */        }	dasd_debug (0xc4c86d6d);	/* DHwu */}static intdasd_format (int dev, format_data_t * fdata){	int rc;	int devindex = DEVICE_NR (dev);	dasd_chanq_t *q;	cqr_t *cqr;	int irq;	long flags;	PRINT_INFO ("Format called with devno %x\n", dev);	if (MINOR (dev) & (0xff >> (8 - PARTN_BITS))) {		PRINT_WARN ("Can't format partition! minor %x %x\n",			    MINOR (dev), 0xff >> (8 - PARTN_BITS));		return -EINVAL;	}	down (&dasd_info[devindex]->sem);	if (dasd_info[devindex]->open_count == 1) {		rc = dasd_disciplines[dasd_info[devindex]->type]->		    dasd_format (devindex, fdata);		if (rc) {			PRINT_WARN ("Formatting failed rc=%d\n", rc);		}	} else {		PRINT_WARN ("device is open! %d\n", dasd_info[devindex]->open_count);		rc = -EINVAL;	}	if (!rc) {#if DASD_PARANOIA > 1		if (!dasd_disciplines[dasd_info[devindex]->type]->fill_sizes_first) {			INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dasd_info[devindex]->type);	} else#endif				/* DASD_PARANOIA */	{		dasd_info[devindex]->flags &= ~DASD_INFO_FLAGS_INITIALIZED;	        irq = dasd_info[devindex]->info.irq;		PRINT_INFO ("Trying to access DASD %x, irq %x, index %d\n",		get_devno_by_irq(irq), irq, devindex);        	s390irq_spin_lock_irqsave (irq, flags);	        q = &dasd_info[devindex]->queue;		cqr = dasd_disciplines[dasd_info[devindex]->type]->			fill_sizes_first (devindex);	        dasd_chanq_enq (q, cqr);		schedule_bh(dasd_do_chanq);        	s390irq_spin_unlock_irqrestore (irq, flags);	}	}	up (&dasd_info[devindex]->sem);	return rc;}static intregister_dasd (int irq, dasd_type_t dt, dev_info_t * info){	int rc = 0;	int di;	unsigned long flags;	dasd_chanq_t *q;	cqr_t * cqr;	static spinlock_t register_lock = SPIN_LOCK_UNLOCKED;	spin_lock (&register_lock);	FUNCTION_ENTRY ("register_dasd");	di = devindex_from_devno (info->devno);	if (di < 0) {		INTERNAL_CHECK ("Can't get index for devno %d\n", info->devno);		return -ENODEV;	}	if (dasd_info[di]) {	/* devindex is not free */		INTERNAL_CHECK ("reusing allocated deviceindex %d\n", di);		return -ENODEV;	}	dasd_info[di] = (dasd_information_t *)	    kmalloc (sizeof (dasd_information_t), GFP_ATOMIC);	if (dasd_info[di] == NULL) {		PRINT_WARN ("No memory for dasd_info_t on irq %d\n", irq);		return -ENOMEM;	}	memset (dasd_info[di], 0, sizeof (dasd_information_t));	memcpy (&(dasd_info[di]->info), info, sizeof (dev_info_t));	spin_lock_init (&dasd_info[di]->queue.f_lock);	spin_lock_init (&dasd_info[di]->queue.q_lock);	dasd_info[di]->type = dt;	dasd_info[di]->irq = irq;        init_MUTEX (&dasd_info[di]->sem);	rc = dasd_read_characteristics (dasd_info[di]);	if (rc) {		PRINT_WARN ("RDC returned error %d\n", rc);		rc = -ENODEV;		goto unalloc;	}#if DASD_PARANOIA > 1	if (dasd_disciplines[dt]->ck_characteristics)#endif				/* DASD_PARANOIA */		rc = dasd_disciplines[dt]->		    ck_characteristics (dasd_info[di]->rdc_data);	if (rc) {		INTERNAL_CHECK ("Discipline returned non-zero when"				"checking device characteristics%s\n", "");		rc = -ENODEV;		goto unalloc;	}	rc = request_irq (irq, dasd_handler, 0, "dasd",			  &(dasd_info[di]->dev_status));	if (rc) {#if DASD_PARANOIA > 0		printk (KERN_WARNING PRINTK_HEADER			"Cannot register irq %d, rc=%d\n",			irq, rc);#endif				/* DASD_PARANOIA */		rc = -ENODEV;		goto unalloc;	}#if DASD_PARANOIA > 1	if (!dasd_disciplines[dt]->fill_sizes_first) {		INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dt);		goto unregister;	}#endif				/* DASD_PARANOIA */        irq = dasd_info[di]->info.irq;	PRINT_INFO ("Trying to access DASD %x, irq %x, index %d\n",	get_devno_by_irq(irq), irq, di);        s390irq_spin_lock_irqsave (irq, flags);        q = &dasd_info[di]->queue;	cqr = dasd_disciplines[dt]->fill_sizes_first (di);        dasd_chanq_enq (q, cqr);        cql_enq_head(q);	if (dasd_start_IO(cqr) != 0) {          atomic_inc(&chanq_tasks);        }        s390irq_spin_unlock_irqrestore (irq, flags);	goto exit;      unregister:	free_irq (irq, &(dasd_info[di]->dev_status));      unalloc:	kfree (dasd_info[di]);      exit:	spin_unlock (&register_lock);	FUNCTION_EXIT ("register_dasd");	return rc;}static intprobe_for_dasd (int irq){	int rc;	dev_info_t info;	dasd_type_t dt;	FUNCTION_ENTRY ("probe_for_dasd");	rc = get_dev_info_by_irq (irq, &info);	if (rc == -ENODEV) {	/* end of device list */		return rc;	}#if DASD_PARANOIA > 2	if (rc) {		INTERNAL_CHECK ("unknown rc %d of get_dev_info", rc);		return rc;	}#endif				/* DASD_PARANOIA */	if ((info.status & DEVSTAT_NOT_OPER)) {		return -ENODEV;	}	dt = check_type (&info);	switch (dt) {#ifdef CONFIG_DASD_ECKD	case dasd_eckd:#endif				/* CONFIG_DASD_ECKD */		FUNCTION_CONTROL ("Probing devno %d...\n", info.devno);		if (!dasd_is_accessible (info.devno)) {			FUNCTION_CONTROL ("out of range...skip%s\n", "");			return -ENODEV;		}		if (dasd_disciplines[dt]->ck_devinfo) {			rc = dasd_disciplines[dt]->ck_devinfo (&info);		}#if DASD_PARANOIA > 1		else {			INTERNAL_ERROR ("no ck_devinfo function%s\n", "");			return -ENODEV;		}#endif				/* DASD_PARANOIA */		if (rc == -ENODEV) {			return rc;		}#if DASD_PARANOIA > 2		if (rc) {			INTERNAL_CHECK ("unknown error rc=%d\n", rc);			return -ENODEV;		}#endif				/* DASD_PARANOIA */		rc = register_dasd (irq, dt, &info);		if (rc) {			PRINT_INFO ("devno %x not enabled as minor %d  due to errors\n",				    info.devno,				    devindex_from_devno (info.devno) <<				    PARTN_BITS);		} else {			PRINT_INFO ("devno %x added as minor %d (%s)\n",				    info.devno,			       devindex_from_devno (info.devno) << PARTN_BITS,				    dasd_name[dt]);		}	case dasd_none:		break;	default:		PRINT_DEBUG ("unknown device type\n");		break;	}	FUNCTION_EXIT ("probe_for_dasd");	return rc;}static intregister_major (int major){        request_queue_t *q;	int rc = 0;	FUNCTION_ENTRY ("register_major");	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);#if DASD_PARANOIA > 1	if (rc) {		PRINT_WARN ("registering major -> rc=%d aborting... \n", rc);		return rc;	}#endif				/* DASD_PARANOIA */        q = BLK_DEFAULT_QUEUE(major);        blk_init_queue(q, do_dasd_request);        blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);	FUNCTION_CONTROL ("successfully registered major: %d\n", major);	FUNCTION_EXIT ("register_major");	return rc;}/*    Below you find functions which are called from outside. Some of them may be   static, because they are called by their function pointers only. Thus static   modifier is to make sure, that they are only called via the kernel's methods */static intdasd_ioctl (struct inode *inp, struct file *filp,	    unsigned int no, unsigned long data){	int rc = 0;	FUNCTION_ENTRY ("dasd_ioctl");	if ((!inp) || !(inp->i_rdev)) {		return -EINVAL;	}	rc = do_dasd_ioctl (inp, no, data);	FUNCTION_EXIT ("dasd_ioctl");	return rc;}static intdasd_open (struct inode *inp, struct file *filp){	int rc = 0;	dasd_information_t *dev;	FUNCTION_ENTRY ("dasd_open");	if ((!inp) || !(inp->i_rdev)) {		return -EINVAL;	}	dev = dasd_info[DEVICE_NR (inp->i_rdev)];	if (!dev) {		PRINT_DEBUG ("No device registered as %d (%d)\n",			    inp->i_rdev, DEVICE_NR (inp->i_rdev));		return -EINVAL;	}	down (&dev->sem);	up (&dev->sem);#ifdef MODULE	MOD_INC_USE_COUNT;#endif				/* MODULE */#if DASD_PARANOIA > 2	if (dev->open_count < 0) {		INTERNAL_ERROR ("open count cannot be less than 0: %d",				dev->open_count);		return -EINVAL;	}#endif				/* DASD_PARANOIA */	dev->open_count++;	FUNCTION_EXIT ("dasd_open");	return rc;}static intdasd_release (struct inode *inp, struct file *filp){	int rc = 0;	dasd_information_t *dev;	FUNCTION_ENTRY ("dasd_release");	if ((!inp) || !(inp->i_rdev)) {		return -EINVAL;	}	dev = dasd_info[DEVICE_NR (inp->i_rdev)];	if (!dev) {		PRINT_WARN ("No device registered as %d\n", inp->i_rdev);		return -EINVAL;	}#ifdef MODULE	MOD_DEC_USE_COUNT;#endif				/* MODULE */#if DASD_PARANOIA > 2	if (!dev->open_count) {		PRINT_WARN ("device %d has not been opened before:\n",			    inp->i_rdev);	}#endif				/* DASD_PARANOIA */	dev->open_count--;#if DASD_PARANOIA > 2	if (dev->open_count < 0) {		INTERNAL_ERROR ("open count cannot be less than 0: %d",				dev->open_count);		return -EINVAL;	}#endif				/* DASD_PARANOIA */	FUNCTION_EXIT ("dasd_release");	return rc;}static structblock_device_operations dasd_device_operations ={	ioctl:   dasd_ioctl,	open:    dasd_open,	release: dasd_release,};intdasd_init (void){	int rc = 0;	int i;	FUNCTION_ENTRY ("dasd_init");	PRINT_INFO ("initializing...\n");	atomic_set (&chanq_tasks, 0);	atomic_set (&bh_scheduled, 0);	spin_lock_init (&dasd_lock);        init_waitqueue_head(&dasd_waitq);	/* First register to the major number */	rc = register_major (MAJOR_NR);#if DASD_PARANOIA > 1	if (rc) {		PRINT_WARN ("registering major_nr returned rc=%d\n", rc);		return rc;	}#endif	/* DASD_PARANOIA */         read_ahead[MAJOR_NR] = 8;        blk_size[MAJOR_NR] = dasd_blks;	hardsect_size[MAJOR_NR] = dasd_secsize;	blksize_size[MAJOR_NR] = dasd_blksize;	max_sectors[MAJOR_NR] = dasd_maxsecs;#ifdef CONFIG_PROC_FS	dasd_proc_init ();#endif				/* CONFIG_PROC_FS */	/* Now scan the device list for DASDs */	FUNCTION_CONTROL ("entering detection loop%s\n", "");	for (i = 0; i < NR_IRQS; i++) {		int irc;	/* Internal return code */		LOOP_CONTROL ("Probing irq %d...\n", i);		irc = probe_for_dasd (i);		switch (irc) {		case 0:			LOOP_CONTROL ("Added DASD%s\n", "");			break;		case -ENODEV:			LOOP_CONTROL ("No DASD%s\n", "");			break;		case -EMEDIUMTYPE:			PRINT_WARN ("DASD not formatted%s\n", "");			break;		default:			INTERNAL_CHECK ("probe_for_dasd: unknown rc=%d", irc);			break;		}	}	FUNCTION_CONTROL ("detection loop completed %s partn check...\n", "");/* Finally do the genhd stuff */	dd_gendisk.next = gendisk_head;	gendisk_head = &dd_gendisk;        for ( i = 0; i < DASD_MAX_DEVICES; i ++ )          if ( dasd_info[i] )                dasd_partn_detect ( i );	FUNCTION_EXIT ("dasd_init");	return rc;}#ifdef MODULEintinit_module (void){	int rc = 0;	FUNCTION_ENTRY ("init_module");	PRINT_INFO ("trying to load module\n");	rc = dasd_init ();	if (rc == 0) {		PRINT_INFO ("module loaded successfully\n");	} else {		PRINT_WARN ("warning: Module load returned rc=%d\n", rc);	}	FUNCTION_EXIT ("init_module");	return rc;}voidcleanup_module (void){	int rc = 0;	FUNCTION_ENTRY ("cleanup_module");	PRINT_INFO ("trying to unload module \n");	/* FIXME: replace by proper unload functionality */	INTERNAL_ERROR ("Modules not yet implemented %s", "");	if (rc == 0) {		PRINT_INFO ("module unloaded successfully\n");	} else {		PRINT_WARN ("module unloaded with errors\n");	}	FUNCTION_EXIT ("cleanup_module");}#endif				/* MODULE *//* * Overrides for Emacs so that we 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 + -