dasd_eckd.c

来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 1,885 行 · 第 1/4 页

C
1,885
字号
	}	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;        cqr->cpaddr->flags |= CCW_FLAG_SLI;        cqr->cpaddr->count = 32;	if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data),                                      cqr, device)) {                dasd_free_request (cqr, device);                return NULL;        }	cqr->device  = device;	cqr->retries = 0;	cqr->expires = 10 * TOD_SEC;	cqr->buildclk = get_clock ();	cqr->status  = CQR_STATUS_FILLED;	return cqr;}/* * DASD_ECKD_STEAL_LOCK * * DESCRIPTION *    Buils a channel programm to break a device's reservation.  *    (unconditional reserve) */ccw_req_t *dasd_eckd_steal_lock (struct dasd_device_t * device){	ccw_req_t *cqr;        cqr = dasd_alloc_request (dasd_eckd_discipline.name,                                   1 + 1, 32, device);	if (cqr == NULL) {		MESSAGE (KERN_WARNING, "%s",			"No memory to allocate initialization request");		return NULL;	}	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;        cqr->cpaddr->flags |= CCW_FLAG_SLI;        cqr->cpaddr->count = 32;	if (dasd_set_normalized_cda (cqr->cpaddr, __pa (cqr->data),                                      cqr, device)) {                dasd_free_request (cqr, device);                return NULL;        }        	cqr->device  = device;	cqr->retries = 0;	cqr->expires = 10 * TOD_SEC;	cqr->buildclk = get_clock ();	cqr->status  = CQR_STATUS_FILLED;	return cqr;}static inline ccw1_t *dasd_eckd_find_cmd (ccw_req_t * cqr, int cmd){	ccw1_t *cp;	cp = cqr->cpaddr;	do {		if (cp->cmd_code == cmd)			return cp;		if (cp->cmd_code == CCW_CMD_TIC) {			cp = (ccw1_t *) (long) cp->cda;			continue;		}		if (cp->flags & (CCW_FLAG_DC | CCW_FLAG_CC)) {			cp++;			continue;		}		break;	} while (1);	return NULL;}static ccw_req_t *dasd_eckd_merge_cp (dasd_device_t * device){	return NULL;}static intdasd_eckd_fill_info (dasd_device_t * device, dasd_information2_t * info){	int rc = 0;	info->label_block = 2;	if (((dasd_eckd_private_t *) device->private)->uses_cdl) {		info->FBA_layout = 0;                info->format = DASD_FORMAT_CDL;        } else {                info->FBA_layout = 1;                info->format = DASD_FORMAT_LDL;        }	info->characteristics_size = sizeof (dasd_eckd_characteristics_t);	memcpy (info->characteristics,		&((dasd_eckd_private_t *) device->private)->rdc_data,		sizeof (dasd_eckd_characteristics_t));	info->confdata_size = sizeof (dasd_eckd_confdata_t);	memcpy (info->configuration_data,		&((dasd_eckd_private_t *) device->private)->conf_data,		sizeof (dasd_eckd_confdata_t));	return rc;}/* * DASD_ECKD_READ_STATS *  * DESCRIPTION *   build the channel program to read the performance statistics *   of the attached subsystem */ccw_req_t *dasd_eckd_read_stats (struct dasd_device_t * device){        int                    rc;	ccw1_t                 *ccw;	ccw_req_t              *cqr;	dasd_psf_prssd_data_t  *prssdp;	dasd_rssd_perf_stats_t *statsp;        cqr = dasd_alloc_request (dasd_eckd_discipline.name,                                   1 /* PSF */ + 1 /* RSSD */,                                  (sizeof (dasd_psf_prssd_data_t) +                                     sizeof (dasd_rssd_perf_stats_t) ),                                   device);	if (cqr == NULL) {                                MESSAGE (KERN_WARNING, "%s",                         "No memory to allocate initialization request");                		return NULL;	}	cqr->device  = device;	cqr->retries = 0;	cqr->expires = 10 * TOD_SEC;        /* Prepare for Read Subsystem Data */	prssdp = (dasd_psf_prssd_data_t *) cqr->data;	memset (prssdp, 0, sizeof (dasd_psf_prssd_data_t));	prssdp->order     = PSF_ORDER_PRSSD;	prssdp->suborder  = 0x01; /* Perfomance Statistics */	prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */	ccw = cqr->cpaddr;	ccw->cmd_code = DASD_ECKD_CCW_PSF;	ccw->count    = sizeof (dasd_psf_prssd_data_t);	ccw->flags   |= CCW_FLAG_CC;	if ((rc = dasd_set_normalized_cda (ccw,__pa (prssdp), cqr, device))) {                dasd_free_request (cqr,                                    device);                return NULL;        }	ccw++;        /* Read Subsystem Data - Performance Statistics */	statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1);	memset (statsp, 0, sizeof (dasd_rssd_perf_stats_t));	ccw->cmd_code = DASD_ECKD_CCW_RSSD;	ccw->count    = sizeof (dasd_rssd_perf_stats_t);	if ((rc = dasd_set_normalized_cda (ccw,__pa (statsp), cqr, device))) {                dasd_free_request (cqr,                                    device);                return NULL;        }        cqr->buildclk = get_clock ();	cqr->status   = CQR_STATUS_FILLED;	return cqr; } /* end  dasd_eckd_rstat *//* * DASD_ECKD_RET_STATS *  * DESCRIPTION *   returns pointer to Performance Statistics Data. */dasd_rssd_perf_stats_t *dasd_eckd_ret_stats (ccw_req_t *cqr){                dasd_psf_prssd_data_t  *prssdp;	dasd_rssd_perf_stats_t *statsp;        	if (cqr == NULL) {		return NULL;	}        /* Prepare for Read Subsystem Data */	prssdp = (dasd_psf_prssd_data_t *)  cqr->data;	statsp = (dasd_rssd_perf_stats_t *) (prssdp + 1);	return statsp;} /* end  dasd_eckd_rstat *//* * DASD_ECKD_GET_ATTRIB *  * DESCRIPTION *   returnes the cache attributes used in Define Extend (DE). */intdasd_eckd_get_attrib (dasd_device_t *device,                      attrib_data_t *attrib){	dasd_eckd_private_t *private;        private = (dasd_eckd_private_t *) device->private;        *attrib = private->attrib;                return 0;        } /* end dasd_eckd_get_attrib *//* * DASD_ECKD_SET_ATTRIB *  * DESCRIPTION *   stores the attributes for cache operation to be used in Define Extend (DE). */intdasd_eckd_set_attrib (dasd_device_t *device,                      attrib_data_t *attrib){	dasd_eckd_private_t *private;        private = (dasd_eckd_private_t *) device->private;        private->attrib = *attrib;        DBF_DEV_EVENT (DBF_ERR, device,                     "cache operation mode set to "                     "%x (%i cylinder prestage)",                     private->attrib.operation,                     private->attrib.nr_cyl);        return 0;        } /* end dasd_eckd_set_attrib */static voiddasd_eckd_dump_sense (struct dasd_device_t *device,                       ccw_req_t            *req){	char *page = (char *) get_free_page (GFP_ATOMIC);	devstat_t *stat = &device->dev_status;	char *sense = stat->ii.sense.data;	int len, sl, sct;	if (page == NULL) {                MESSAGE (KERN_ERR, "%s",                        "No memory to dump sense data");		return;	}	len = sprintf (page, KERN_ERR PRINTK_HEADER		       "device %04X on irq %d: I/O status report:\n",		       device->devinfo.devno, device->devinfo.irq);	len += sprintf (page + len, KERN_ERR PRINTK_HEADER			"in req: %p CS: 0x%02X DS: 0x%02X\n",			req, stat->cstat, stat->dstat);	len += sprintf (page + len, KERN_ERR PRINTK_HEADER			"Failing CCW: %p\n", (void *) (long) stat->cpa);	{		ccw1_t *act = req->cpaddr;		int i = req->cplength;		do {			DBF_EVENT (DBF_INFO,                                    "CCW %p: %08X %08X",                                   act,                                    ((int *) act)[0],                                    ((int *) act)[1]);			DBF_EVENT (DBF_INFO,                                    "DAT: %08X %08X %08X %08X",                                   ((int *) (addr_t) act->cda)[0],                                    ((int *) (addr_t) act->cda)[1],                                   ((int *) (addr_t) act->cda)[2],                                    ((int *) (addr_t) act->cda)[3]);			act++;		} while (--i);	}	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {		for (sl = 0; sl < 4; sl++) {			len += sprintf (page + len, KERN_ERR PRINTK_HEADER					"Sense(hex) %2d-%2d:",					(8 * sl), ((8 * sl) + 7));			for (sct = 0; sct < 8; sct++) {				len += sprintf (page + len, " %02x",						sense[8 * sl + sct]);			}			len += sprintf (page + len, "\n");		}		if (sense[27] & DASD_SENSE_BIT_0) {			/* 24 Byte Sense Data */			len += sprintf (page + len, KERN_ERR PRINTK_HEADER					"24 Byte: %x MSG %x, %s MSGb to SYSOP\n",					sense[7] >> 4, sense[7] & 0x0f,					sense[1] & 0x10 ? "" : "no");		} else {			/* 32 Byte Sense Data */			len += sprintf (page + len, KERN_ERR PRINTK_HEADER					"32 Byte: Format: %x "                                        "Exception class %x\n",					sense[6] & 0x0f, sense[22] >> 4);		}	}        MESSAGE_LOG (KERN_ERR,                     "Sense data:\n%s",                      page);        free_page ((unsigned long) page);}dasd_discipline_t dasd_eckd_discipline = {        owner: THIS_MODULE,	name:"ECKD",	ebcname:"ECKD",	max_blocks:240,	id_check:dasd_eckd_id_check,	check_characteristics:dasd_eckd_check_characteristics,	init_analysis:dasd_eckd_init_analysis,	do_analysis:dasd_eckd_do_analysis,	fill_geometry:dasd_eckd_fill_geometry,	start_IO:dasd_start_IO,	term_IO:dasd_term_IO,	format_device:dasd_eckd_format_device,	examine_error:dasd_eckd_examine_error,	erp_action:dasd_eckd_erp_action,	erp_postaction:dasd_eckd_erp_postaction,	build_cp_from_req:dasd_eckd_build_cp_from_req,	dump_sense:dasd_eckd_dump_sense,	int_handler:dasd_int_handler,	reserve:dasd_eckd_reserve,	release:dasd_eckd_release,        steal_lock:dasd_eckd_steal_lock,	merge_cp:dasd_eckd_merge_cp,	fill_info:dasd_eckd_fill_info,        read_stats:dasd_eckd_read_stats,        ret_stats:dasd_eckd_ret_stats,        get_attrib:dasd_eckd_get_attrib,        set_attrib:dasd_eckd_set_attrib,	list:LIST_HEAD_INIT(dasd_eckd_discipline.list),};intdasd_eckd_init (void){	int rc = 0;	MESSAGE (KERN_INFO,		"%s discipline initializing",                  dasd_eckd_discipline.name);	ASCEBC (dasd_eckd_discipline.ebcname, 4);	dasd_discipline_add (&dasd_eckd_discipline);#ifdef CONFIG_DASD_DYNAMIC	{		int i;		for (i = 0;		     i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t);		     i++) {			MESSAGE (KERN_INFO,                                 "We are interested in: CU %04X/%02x",                                 dasd_eckd_known_devices[i].ci.hc.ctype,                                 dasd_eckd_known_devices[i].ci.hc.cmode);			s390_device_register (&dasd_eckd_known_devices[i]);		}	}#endif				/* CONFIG_DASD_DYNAMIC */	return rc;}voiddasd_eckd_cleanup (void){	MESSAGE (KERN_INFO,		"%s discipline cleaning up",                  dasd_eckd_discipline.name);#ifdef CONFIG_DASD_DYNAMIC	{		int i;		for (i = 0;		     i < sizeof (dasd_eckd_known_devices) / sizeof (devreg_t);		     i++) {			MESSAGE (KERN_INFO,                                 "We were interested in: CU %04X/%02x",                                 dasd_eckd_known_devices[i].ci.hc.ctype,                                 dasd_eckd_known_devices[i].ci.hc.cmode);			s390_device_unregister (&dasd_eckd_known_devices[i]);		}	}#endif				/* CONFIG_DASD_DYNAMIC */	dasd_discipline_del (&dasd_eckd_discipline);}#ifdef MODULEintinit_module (void){	int rc = 0;	rc = dasd_eckd_init ();	return rc;}voidcleanup_module (void){	dasd_eckd_cleanup ();	return;}#endif/* * 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 + =
减小字号Ctrl + -
显示快捷键?