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

📄 dasd_eckd.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	eckd_count_t *count_data = private->count_area;	cqr = dasd_alloc_request (dasd_eckd_discipline.name, 8 + 1,				 sizeof (DE_eckd_data_t) +				 2 * sizeof (LO_eckd_data_t),                                 device);	if (cqr == NULL) {                printk (KERN_WARNING PRINTK_HEADER                        "No memory to allocate initialization request\n");                goto out;	}	DE_data = cqr->data;	LO_data = cqr->data + sizeof (DE_eckd_data_t);	ccw = cqr->cpaddr;	if (define_extent (ccw, DE_data, 0, 2, DASD_ECKD_CCW_READ_COUNT, device, cqr)) {                goto clear_cqr;        }        	ccw->flags |= CCW_FLAG_CC;	ccw++;	if (locate_record (ccw, LO_data++, 0, 0, 4, DASD_ECKD_CCW_READ_COUNT,                           device, 0, cqr)) {                goto clear_cqr;        }       	ccw->flags |= CCW_FLAG_CC;	ccw++;	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;	ccw->count = 8;	if (dasd_set_normalized_cda (ccw, __pa (count_data++), cqr, device)) {                goto clear_cqr;        }	ccw->flags |= CCW_FLAG_CC;	ccw++;	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;	ccw->count = 8;	if (dasd_set_normalized_cda (ccw, __pa (count_data++), cqr, device)) {                goto clear_cqr;        }	ccw->flags |= CCW_FLAG_CC;	ccw++;	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;	ccw->count = 8;	if (dasd_set_normalized_cda (ccw, __pa (count_data++), cqr, device)) {                goto clear_cqr;        }	ccw->flags |= CCW_FLAG_CC;	ccw++;	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;	ccw->count = 8;	if (dasd_set_normalized_cda (ccw, __pa (count_data++), cqr, device)) {                goto clear_cqr;        }	ccw->flags |= CCW_FLAG_CC;	ccw++;	if (locate_record (ccw, LO_data++, 2, 0, 1, DASD_ECKD_CCW_READ_COUNT,                           device, 0, cqr)) {                goto clear_cqr;        }       	ccw->flags |= CCW_FLAG_CC;	ccw++;	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;	ccw->count = 8;	if (dasd_set_normalized_cda (ccw, __pa (count_data), cqr, device)) {                goto clear_cqr;        }	cqr->device = device;	cqr->retries = 0;	cqr->status = CQR_STATUS_FILLED;        dasd_chanq_enq (&device->queue, cqr);        goto out; clear_cqr:        dasd_free_request (cqr,device);        printk (KERN_WARNING PRINTK_HEADER                "No memory to allocate initialization request\n");        cqr=NULL; out:	return cqr;}static intdasd_eckd_do_analysis (struct dasd_device_t *device){	int sb, rpt;	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;	eckd_count_t *count_area = NULL;	char *cdl_msg;        int status;	int i;	private->uses_cdl = 1;        status = device->init_cqr->status;	dasd_chanq_deq (&device->queue, device->init_cqr);	dasd_free_request (device->init_cqr, device);	/* Free the cqr and cleanup device->sizes */        if ( status != CQR_STATUS_DONE ) {                DASD_MESSAGE (KERN_WARNING,device,"%s",                              "volume analysis returned unformatted disk");                return -EMEDIUMTYPE;        }	/* Check Track 0 for Compatible Disk Layout */	for (i = 0; i < 3; i++) {		if ((i < 3) &&		    ((private->count_area[i].kl != 4) ||		     (private->count_area[i].dl !=		      dasd_eckd_cdl_reclen (device, i) - 4))) {			private->uses_cdl = 0;			break;		}	}	if (i == 3) {		count_area = &private->count_area[4];	}	if (private->uses_cdl == 0) {		for (i = 0; i < 5; i++) {			if ((private->count_area[i].kl != 0) ||			    (private->count_area[i].dl !=			     private->count_area[0].dl)) {				break;			}		}		if (i == 5) {			count_area = &private->count_area[0];		}	} else {		if (private->count_area[3].record == 1) {			DASD_MESSAGE (KERN_WARNING, device, "%s",				      "Trk 0: no records after VTOC!");		}	}	if (count_area != NULL &&	/* we found notthing violating our disk layout */	    count_area->kl == 0) {                /* find out blocksize */                switch (count_area->dl) {                case 512:		case 1024:		case 2048:		case 4096:			device->sizes.bp_block = count_area->dl;			break;		}	}	if (device->sizes.bp_block == 0) {		DASD_MESSAGE (KERN_WARNING, device, "%s",			      "Volume has incompatible disk layout");		return -EMEDIUMTYPE;	}	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */	device->sizes.pt_block = 2;	for (sb = 512; sb < device->sizes.bp_block; sb = sb << 1)		device->sizes.s2b_shift++;	rpt = recs_per_track (&private->rdc_data, 0, device->sizes.bp_block);	device->sizes.blocks = (private->rdc_data.no_cyl *				private->rdc_data.trk_per_cyl *				recs_per_track (&private->rdc_data, 0,						device->sizes.bp_block));	cdl_msg =	    private->	    uses_cdl ? "compatible disk layout" : "classic disk layout";	DASD_MESSAGE (KERN_INFO, device, "(%dkB blks): %dkB at %dkB/trk %s",		      (device->sizes.bp_block >> 10),		      (private->rdc_data.no_cyl *		       private->rdc_data.trk_per_cyl *		       recs_per_track (&private->rdc_data, 0,				       device->sizes.bp_block) *		       (device->sizes.bp_block >> 9)) >> 1,		      (recs_per_track (&private->rdc_data, 0,				       device->sizes.bp_block) *		       device->sizes.bp_block) >> 10, cdl_msg);	return 0;}static intdasd_eckd_fill_geometry (struct dasd_device_t *device, struct hd_geometry *geo){	int rc = 0;	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;	switch (device->sizes.bp_block) {	case 512:	case 1024:	case 2048:	case 4096:            geo->sectors = recs_per_track (&(private->rdc_data),                                            0, device->sizes.bp_block);            break;	default:            break;	}	geo->cylinders = private->rdc_data.no_cyl;	geo->heads = private->rdc_data.trk_per_cyl;	return rc;}static ccw_req_t *dasd_eckd_format_device (dasd_device_t * device, format_data_t * fdata){	int i;	ccw_req_t *fcp = NULL;	DE_eckd_data_t *DE_data = NULL;	LO_eckd_data_t *LO_data = NULL;	eckd_count_t *ct_data = NULL;	eckd_count_t *r0_data = NULL;	eckd_home_t *ha_data = NULL;	ccw1_t *last_ccw = NULL;	void *last_data = NULL;	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;	int rpt = recs_per_track (&(private->rdc_data), 0, fdata->blksize);	int cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;	int head = fdata->start_unit % private->rdc_data.trk_per_cyl;	int wrccws = rpt;	int datasize = sizeof (DE_eckd_data_t) + sizeof (LO_eckd_data_t);        	if (fdata->start_unit >= (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)){                DASD_MESSAGE (KERN_INFO, device, "Track no %d too big!", fdata->start_unit);                return NULL;        }        if ( fdata->start_unit > fdata->stop_unit) {                DASD_MESSAGE (KERN_INFO, device, "Track %d reached! ending.",                              fdata->start_unit);		return NULL;	}	switch (fdata->blksize) {	case 512:	case 1024:	case 2048:	case 4096:		break;	default:		printk (KERN_WARNING PRINTK_HEADER			"Invalid blocksize %d...terminating!\n", fdata->blksize);		return NULL;	}	switch (fdata->intensity) {	case 0x00:	case 0x01:	case 0x03:	case 0x04:		/* make track invalid */	case 0x08:	case 0x09:	case 0x0b:	case 0x0c:		break;	default:		printk (KERN_WARNING PRINTK_HEADER			"Invalid flags 0x%x...terminating!\n", fdata->intensity);		return NULL;	}	/* print status line */	if ((private->rdc_data.no_cyl < 20) ?	    (fdata->start_unit % private->rdc_data.no_cyl == 0) :	    (fdata->start_unit % private->rdc_data.no_cyl == 0 &&	     (fdata->start_unit / private->rdc_data.no_cyl) %	     (private->rdc_data.no_cyl / 20))) {		DASD_MESSAGE (KERN_INFO, device,			      "Format Cylinder: %d Flags: %d",			      fdata->start_unit / private->rdc_data.trk_per_cyl, fdata->intensity);	}	if ((fdata->intensity & ~0x8) & 0x04) {		wrccws = 1;		rpt = 1;	} else {		if (fdata->intensity & 0x1) {			wrccws++;			datasize += sizeof (eckd_count_t);		}		if (fdata->intensity & 0x2) {			wrccws++;			datasize += sizeof (eckd_home_t);		}	}	fcp = dasd_alloc_request (dasd_eckd_discipline.name,				 wrccws + 2 + 1,				 datasize + rpt * sizeof (eckd_count_t),                                 device );	if (fcp != NULL) {		fcp->device = device;		fcp->retries = 2;	/* set retry counter to enable ERP */		last_data = fcp->data;		DE_data = (DE_eckd_data_t *) last_data;		last_data = (void *) (DE_data + 1);		LO_data = (LO_eckd_data_t *) last_data;		last_data = (void *) (LO_data + 1);		if (fdata->intensity & 0x2) {			ha_data = (eckd_home_t *) last_data;			last_data = (void *) (ha_data + 1);		}		if (fdata->intensity & 0x1) {			r0_data = (eckd_count_t *) last_data;			last_data = (void *) (r0_data + 1);		}		ct_data = (eckd_count_t *) last_data;		last_ccw = fcp->cpaddr;		switch (fdata->intensity & ~0x08) {		case 0x03:			if (define_extent (last_ccw, DE_data, fdata->start_unit, fdata->start_unit,				       DASD_ECKD_CCW_WRITE_HOME_ADDRESS,                                           device, fcp)) {                                goto clear_fcp;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws,				       DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device,                                           device->sizes.bp_block, fcp)) {                                goto clear_fcp;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			break;		case 0x01:			if (define_extent (last_ccw, DE_data, fdata->start_unit, fdata->start_unit,                                           DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, fcp)) {                                goto clear_fcp;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws,				       DASD_ECKD_CCW_WRITE_RECORD_ZERO, device,                                           device->sizes.bp_block, fcp)) {                                goto clear_fcp;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			memset (r0_data, 0, sizeof (eckd_count_t));			break;		case 0x04:                        fdata->blksize = 8;		case 0x00:			if (define_extent (last_ccw, DE_data, fdata->start_unit, fdata->start_unit,                                           DASD_ECKD_CCW_WRITE_CKD, device, fcp)) {                                dasd_free_request (fcp, device);                                return NULL;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			if (locate_record (last_ccw, LO_data, fdata->start_unit, 0, wrccws,                                           DASD_ECKD_CCW_WRITE_CKD, device, fdata->blksize, fcp)) {                                goto clear_fcp;                        }			last_ccw->flags |= CCW_FLAG_CC;			last_ccw++;			break;		default:			PRINT_WARN ("Unknown format flags...%d\n", fdata->intensity);			return NULL;		}		if (fdata->intensity & 0x02) {			PRINT_WARN ("Unsupported format flag...%d\n", fdata->intensity);			return NULL;		}		if (fdata->intensity & 0x01) {	/* write record zero */			r0_data->cyl = cyl;			r0_data->head = head;			r0_data->record = 0;			r0_data->kl = 0;			r0_data->dl = 8;			last_ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO;			last_ccw->count = 8;			last_ccw->flags |= CCW_FLAG_CC | CCW_FLAG_SLI;			if (dasd_set_normalized_cda (last_ccw, __pa (r0_data), fcp, device)) {                                goto clear_fcp;                        }			last_ccw++;		}		if ((fdata->intensity & ~0x08) & 0x04) {	/* erase track */			memset (ct_data, 0, sizeof (eckd_count_t));			ct_data->cyl = cyl;			ct_data->head = head;			ct_data->record = 1;			ct_data->kl = 0;			ct_data->dl = 0;			last_ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;			last_ccw->count = 8;			last_ccw->flags |= CCW_FLAG_CC | CCW_FLAG_SLI;			if (dasd_set_normalized_cda (last_ccw, __pa (ct_data), fcp, device)) {                                goto clear_fcp;                        }			last_ccw++;		} else {	/* write remaining records */			for (i = 0; i < rpt; i++) {				memset (ct_data + i, 0, sizeof (eckd_count_t));				(ct_data + i)->cyl = cyl;				(ct_data + i)->head = head;				(ct_data + i)->record = i + 1;				(ct_data + i)->kl = 0;				if (fdata->intensity & 0x08) {					// special handling when formatting CDL					switch (fdata->start_unit) {					case 0:						if (i < 3) {							(ct_data + i)->kl = 4;														    (ct_data + i)->dl =							    sizes_trk0[i] - 4;						} else							(ct_data + i)->dl = fdata->blksize;						break;					case 1:						(ct_data + i)->kl = 44;						(ct_data + i)->dl = LABEL_SIZE - 44;						break;					default:						(ct_data + i)->dl = fdata->blksize;						break;					}				} else					(ct_data + i)->dl = fdata->blksize;				last_ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;				last_ccw->flags |= CCW_FLAG_CC | CCW_FLAG_SLI;				last_ccw->count = 8;				if (dasd_set_normalized_cda (last_ccw,                                                             __pa (ct_data + i), fcp, device)) {                                goto clear_fcp;                                }				last_ccw++;			}		}		(last_ccw - 1)->flags &= ~(CCW_FLAG_CC | CCW_FLAG_DC);		fcp->device = device;		fcp->status = CQR_STATUS_FILLED;	}        goto out; clear_fcp:        dasd_free_request (fcp, device);        fcp=NULL; out:	return fcp;}static dasd_era_tdasd_eckd_examine_error (ccw_req_t * cqr, devstat_t * stat){	dasd_device_t *device = (dasd_device_t *) cqr->device;	if (stat->cstat == 0x00 &&	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))		    return dasd_era_none;	switch (device->devinfo.sid_data.cu_type) {	case 0x3990:	case 0x2105:		return dasd_3990_erp_examine (cqr, stat);	case 0x9343:		return dasd_9343_erp_examine (cqr, stat);	default:		printk (KERN_WARNING PRINTK_HEADER			"default (unknown CU type) - RECOVERABLE return \n");		return dasd_era_recover;	}}static dasd_erp_action_fn_tdasd_eckd_erp_action (ccw_req_t * cqr){	dasd_device_t *device = (dasd_device_t *) cqr->device;	switch (device->devinfo.sid_data.cu_type) {	case 0x3990:	case 0x2105:		return dasd_3990_erp_action;	case 0x9343:		/* Return dasd_9343_erp_action; */	default:		return dasd_default_erp_action;	}}static dasd_erp_postaction_fn_tdasd_eckd_erp_postaction (ccw_req_t * cqr){	return dasd_default_erp_postaction;}inline unsigned chardasd_eckd_cdl_cmd (dasd_device_t * device, int recid, int cmd){	dasd_eckd_private_t *private = (dasd_eckd_private_t *) device->private;	int byt_per_blk = device->sizes.bp_block;	int blk_per_trk = recs_per_track (&(private->rdc_data), 0, byt_per_blk);	switch (cmd) {	case READ:		if (recid < 3)			return DASD_ECKD_CCW_READ_KD_MT;		if (recid < blk_per_trk)			return DASD_ECKD_CCW_READ_MT;		if (recid < 2 * blk_per_trk)			return DASD_ECKD_CCW_READ_KD_MT;		return DASD_ECKD_CCW_READ_MT;		break;

⌨️ 快捷键说明

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