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

📄 dasd_eckd.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * File...........: linux/drivers/s390/block/dasd_eckd.c * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 */#include <linux/stddef.h>#include <linux/kernel.h>#ifdef MODULE#include <linux/module.h>#endif				/* MODULE */#include <linux/malloc.h>#include <linux/dasd.h>#include <asm/io.h>#include <asm/irq.h>#include "dasd_types.h"#include "dasd_ccwstuff.h"#ifdef PRINTK_HEADER#undef PRINTK_HEADER#endif				/* PRINTK_HEADER */#define PRINTK_HEADER "dasd(eckd):"#define ECKD_C0(i) (i->home_bytes)#define ECKD_F(i) (i -> formula)#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):(i->factors.f_0x02.f1))#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):(i->factors.f_0x02.f2))#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):(i->factors.f_0x02.f3))#define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)#define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)#define ECKD_F6(i) (i -> factor6)#define ECKD_F7(i) (i -> factor7)#define ECKD_F8(i) (i -> factor8)#define DASD_ECKD_CCW_LOCATE_RECORD 0x47#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a#define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15#define DASD_ECKD_CCW_READ_COUNT 0x12#define DASD_ECKD_CCW_READ 0x06#define DASD_ECKD_CCW_READ_MT 0x86#define DASD_ECKD_CCW_WRITE 0x05#define DASD_ECKD_CCW_WRITE_MT 0x85#define DASD_ECKD_CCW_READ_CKD 0x1e#define DASD_ECKD_CCW_READ_CKD_MT 0x9e#define DASD_ECKD_CCW_WRITE_CKD 0x1d#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9dtypedefstruct {	__u16 cyl;	__u16 head;} __attribute__ ((packed))ch_t;typedefstruct {	__u16 cyl;	__u16 head;	__u32 sector;} __attribute__ ((packed))chs_t;typedefstruct {	__u16 cyl;	__u16 head;	__u8 record;} __attribute__ ((packed))chr_t;typedefstruct {	__u16 cyl;	__u16 head;	__u32 sector;} geom_t;typedef struct {	struct {		struct {			unsigned char identifier:2;			unsigned char token_id:1;			unsigned char sno_valid:1;			unsigned char subst_sno:1;			unsigned char recNED:1;			unsigned char emuNED:1;			unsigned char reserved:1;		} __attribute__ ((packed)) flags;		__u8 descriptor;		__u8 dev_class;		__u8 reserved;		unsigned char dev_type[6];		unsigned char dev_model[3];		unsigned char HDA_manufacturer[3];		unsigned char HDA_location[2];		unsigned char HDA_seqno[12];		__u16 ID;	} __attribute__ ((packed)) ned1;	struct {		struct {			unsigned char identifier:2;			unsigned char token_id:1;			unsigned char sno_valid:1;			unsigned char subst_sno:1;			unsigned char recNED:1;			unsigned char emuNED:1;			unsigned char reserved:1;		} __attribute__ ((packed)) flags;		__u8 descriptor;		__u8 reserved[2];		unsigned char dev_type[6];		unsigned char dev_model[3];		unsigned char DASD_manufacturer[3];		unsigned char DASD_location[2];		unsigned char DASD_seqno[12];		__u16 ID;	} __attribute__ ((packed)) ned2;	struct {		struct {			unsigned char identifier:2;			unsigned char token_id:1;			unsigned char sno_valid:1;			unsigned char subst_sno:1;			unsigned char recNED:1;			unsigned char emuNED:1;			unsigned char reserved:1;		} __attribute__ ((packed)) flags;		__u8 descriptor;		__u8 reserved[2];		unsigned char cont_type[6];		unsigned char cont_model[3];		unsigned char cont_manufacturer[3];		unsigned char cont_location[2];		unsigned char cont_seqno[12];		__u16 ID;	} __attribute__ ((packed)) ned3;	struct {		struct {			unsigned char identifier:2;			unsigned char token_id:1;			unsigned char sno_valid:1;			unsigned char subst_sno:1;			unsigned char recNED:1;			unsigned char emuNED:1;			unsigned char reserved:1;		} __attribute__ ((packed)) flags;		__u8 descriptor;		__u8 reserved[2];		unsigned char cont_type[6];		unsigned char empty[3];		unsigned char cont_manufacturer[3];		unsigned char cont_location[2];		unsigned char cont_seqno[12];		__u16 ID;	} __attribute__ ((packed)) ned4;	unsigned char ned5[32];	unsigned char ned6[32];	unsigned char ned7[32];	struct {		struct {			unsigned char identifier:2;			unsigned char reserved:6;		} __attribute__ ((packed)) flags;		__u8 selector;		__u16 interfaceID;		__u32 reserved;		__u16 subsystemID;		struct {			unsigned char sp0:1;			unsigned char sp1:1;			unsigned char reserved:5;			unsigned char scluster:1;		} __attribute__ ((packed)) spathID;		__u8 unit_address;		__u8 dev_ID;		__u8 dev_address;		__u8 adapterID;		__u16 link_address;		struct {			unsigned char parallel:1;			unsigned char escon:1;			unsigned char reserved:1;			unsigned char ficon:1;			unsigned char reserved2:4;		} __attribute__ ((packed)) protocol_type;		struct {			unsigned char PID_in_236:1;			unsigned char reserved:7;		} __attribute__ ((packed)) format_flags;		__u8 log_dev_address;		unsigned char reserved2[12];	} __attribute__ ((packed)) neq;} __attribute__ ((packed))eckd_confdata_t;typedefstruct {	struct {		unsigned char perm:2;	/* Permissions on this extent */		unsigned char reserved:1;		unsigned char seek:2;	/* Seek control */		unsigned char auth:2;	/* Access authorization */		unsigned char pci:1;	/* PCI Fetch mode */	} __attribute__ ((packed)) mask;	struct {		unsigned char mode:2;	/* Architecture mode */		unsigned char ckd:1;	/* CKD Conversion */		unsigned char operation:3;	/* Operation mode */		unsigned char cfw:1;	/* Cache fast write */		unsigned char dfw:1;	/* DASD fast write */	} __attribute__ ((packed)) attributes;	__u16 short blk_size;	/* Blocksize */	__u16 fast_write_id;	__u8 unused;	__u8 reserved;	ch_t beg_ext;	ch_t end_ext;} __attribute__ ((packed, aligned (32)))DE_eckd_data_t;typedefstruct {	struct {		unsigned char orientation:2;		unsigned char operation:6;	} __attribute__ ((packed)) operation;	struct {		unsigned char last_bytes_used:1;		unsigned char reserved:6;		unsigned char read_count_suffix:1;	} __attribute__ ((packed)) auxiliary;	__u8 unused;	__u8 count;	ch_t seek_addr;	chr_t search_arg;	__u8 sector;	__u16 length;} __attribute__ ((packed, aligned (32)))LO_eckd_data_t;/* Stuff for handling home addresses */typedef struct {	__u8 skip_control[14];	__u16 cell_number;	__u8 physical_addr[3];	__u8 flag;	ch_t track_addr;	__u8 reserved;	__u8 key_length;	__u8 reserved2[2];} __attribute__ ((packed, aligned (32)))eckd_home_t;static unsigned intround_up_multiple (unsigned int no, unsigned int mult){	int rem = no % mult;	return (rem ? no - rem + mult : no);/*      return (no % mult ? no - (no % mult) + mult : no); */}static unsigned intceil_quot (unsigned int d1, unsigned int d2){	return (d1 + (d2 - 1)) / d2;}static intbytes_per_record (dasd_eckd_characteristics_t * rdc,		  int kl,	/* key length */		  int dl /* data length */ ){	int bpr = 0;	switch (rdc->formula) {	case 0x01:{			unsigned int fl1, fl2;			fl1 = round_up_multiple (ECKD_F2 (rdc) + dl,						 ECKD_F1 (rdc));			fl2 = round_up_multiple (kl ? ECKD_F2 (rdc) + kl : 0,						 ECKD_F1 (rdc));			bpr = fl1 + fl2;			break;		}	case 0x02:{			unsigned int fl1, fl2, int1, int2;			int1 = ceil_quot (dl + ECKD_F6 (rdc),					  ECKD_F5 (rdc) << 1);			int2 = ceil_quot (kl + ECKD_F6 (rdc),					  ECKD_F5 (rdc) << 1);			fl1 = round_up_multiple (ECKD_F1 (rdc) *						 ECKD_F2 (rdc) +						 (dl + ECKD_F6 (rdc) +						  ECKD_F4 (rdc) * int1),						 ECKD_F1 (rdc));			fl2 = round_up_multiple (ECKD_F1 (rdc) *						 ECKD_F3 (rdc) +						 (kl + ECKD_F6 (rdc) +						  ECKD_F4 (rdc) * int2),						 ECKD_F1 (rdc));			bpr = fl1 + fl2;			break;		}	default:		INTERNAL_ERROR ("unknown formula%d\n", rdc->formula);	}	return bpr;}static inline unsigned intbytes_per_track (dasd_eckd_characteristics_t * rdc){	return *(unsigned int *) (rdc->byte_per_track) >> 8;}static unsigned intrecs_per_track (dasd_eckd_characteristics_t * rdc,		unsigned int kl, unsigned int dl){	int rpt = 0;	int dn;        switch ( rdc -> dev_type ) {	case 0x3380: 		if (kl)			return 1499 / (15 +				       7 + ceil_quot (kl + 12, 32) +				       ceil_quot (dl + 12, 32));		else			return 1499 / (15 + ceil_quot (dl + 12, 32));	case 0x3390: 		dn = ceil_quot (dl + 6, 232) + 1;		if (kl) {			int kn = ceil_quot (kl + 6, 232) + 1;			return 1729 / (10 +				       9 + ceil_quot (kl + 6 * kn, 34) +				       9 + ceil_quot (dl + 6 * dn, 34));		} else			return 1729 / (10 +				       9 + ceil_quot (dl + 6 * dn, 34));	case 0x9345: 	        dn = ceil_quot (dl + 6, 232) + 1;                if (kl) {                        int kn = ceil_quot (kl + 6, 232) + 1;                        return 1420 / (18 +                                       7 + ceil_quot (kl + 6 * kn, 34) +                                       ceil_quot (dl + 6 * dn, 34));                } else                        return 1420 / (18 +                                       7 + ceil_quot (dl + 6 * dn, 34));	}	return rpt;}staticvoiddefine_extent (ccw1_t * de_ccw,	       DE_eckd_data_t * data,	       int trk,	       int totrk,	       int cmd,	       dasd_information_t * info){	ch_t geo, beg, end;	geo.cyl = info->rdc_data->eckd.no_cyl;	geo.head = info->rdc_data->eckd.trk_per_cyl;	beg.cyl = trk / geo.head;	beg.head = trk % geo.head;	end.cyl = totrk / geo.head;	end.head = totrk % geo.head;	memset (de_ccw, 0, sizeof (ccw1_t));	de_ccw->cmd_code = CCW_DEFINE_EXTENT;	de_ccw->count = 16;	de_ccw->cda = (void *) virt_to_phys (data);	memset (data, 0, sizeof (DE_eckd_data_t));	switch (cmd) {	case DASD_ECKD_CCW_READ_HOME_ADDRESS:	case DASD_ECKD_CCW_READ_RECORD_ZERO:	case DASD_ECKD_CCW_READ:	case DASD_ECKD_CCW_READ_MT:	case DASD_ECKD_CCW_READ_CKD:	/* Fallthrough */	case DASD_ECKD_CCW_READ_CKD_MT:	case DASD_ECKD_CCW_READ_COUNT:		data->mask.perm = 0x1;                data->attributes.operation = 0x3; /* enable seq. caching */		break;	case DASD_ECKD_CCW_WRITE:	case DASD_ECKD_CCW_WRITE_MT:                data->attributes.operation = 0x3; /* enable seq. caching */		break;	case DASD_ECKD_CCW_WRITE_CKD:	case DASD_ECKD_CCW_WRITE_CKD_MT:		data->attributes.operation = 0x1;	/* format through cache */		break;	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:		data->mask.perm = 0x3;		data->mask.auth = 0x1;		data->attributes.operation = 0x1;	/* format through cache */		break;	default:		INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);		break;	}	data->attributes.mode = 0x3;	data->beg_ext.cyl = beg.cyl;	data->beg_ext.head = beg.head;	data->end_ext.cyl = end.cyl;	data->end_ext.head = end.head;}static inline voidlocate_record (ccw1_t * lo_ccw,	       LO_eckd_data_t * data,	       int trk,	       int rec_on_trk,	       int no_rec,	       int cmd,	       dasd_information_t * info){	ch_t geo =	{info->rdc_data->eckd.no_cyl,	 info->rdc_data->eckd.trk_per_cyl};	ch_t seek =	{trk / (geo.head), trk % (geo.head)};	int reclen = info->sizes.bp_block;	memset (lo_ccw, 0, sizeof (ccw1_t));	lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;	lo_ccw->count = 16;	lo_ccw->cda = (void *) virt_to_phys (data);	memset (data, 0, sizeof (LO_eckd_data_t));	switch (cmd) {	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:		data->operation.orientation = 0x3;		data->operation.operation = 0x03;		break;	case DASD_ECKD_CCW_READ_HOME_ADDRESS:		data->operation.orientation = 0x3;		data->operation.operation = 0x16;		break;	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:		data->operation.orientation = 0x3;		data->operation.operation = 0x03;		data->count++;		break;	case DASD_ECKD_CCW_READ_RECORD_ZERO:		data->operation.orientation = 0x3;		data->operation.operation = 0x16;		data->count++;		break;	case DASD_ECKD_CCW_WRITE:	case DASD_ECKD_CCW_WRITE_MT:		data->auxiliary.last_bytes_used = 0x1;		data->length = reclen;		data->operation.operation = 0x01;		break;	case DASD_ECKD_CCW_WRITE_CKD:	case DASD_ECKD_CCW_WRITE_CKD_MT:		data->auxiliary.last_bytes_used = 0x1;		data->length = reclen;		data->operation.operation = 0x03;		break;	case DASD_ECKD_CCW_READ:	case DASD_ECKD_CCW_READ_MT:		data->auxiliary.last_bytes_used = 0x1;

⌨️ 快捷键说明

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