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

📄 libscsi.c

📁 读取SCSI磁盘阵列信息的源代码,支持设备:mega scsi device
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "libscsi.h"/* ioctl */struct megascsi_adapter *mega_scsi_adapter;unsigned char	megascsi_adapt_no;int	megascsi_ioctl_initialized = 0;char dv_xname[] = "PERCSCSI";  unsigned int	USCSICMD = 0x80; voidmegascsi_copyhds(scsi_adapter, sizes, props, stats)	struct megascsi_adapter *scsi_adapter;	const unsigned int *sizes;	const unsigned char *props, *stats;{	int i;	for (i = 0; i < scsi_adapter->adapter_nunits; i++) {		scsi_adapter->adapter_hdr[i].hd_present = 1;		scsi_adapter->adapter_hdr[i].hd_is_logdrv = 1;		scsi_adapter->adapter_hdr[i].hd_size = letoh32(sizes[i]);		scsi_adapter->adapter_hdr[i].hd_prop = props[i];		scsi_adapter->adapter_hdr[i].hd_stat = stats[i];		if (scsi_adapter->adapter_hdr[i].hd_size > 0x200000) {			scsi_adapter->adapter_hdr[i].hd_heads = 255;			scsi_adapter->adapter_hdr[i].hd_secs = 63;		} else {			scsi_adapter->adapter_hdr[i].hd_heads = 64;			scsi_adapter->adapter_hdr[i].hd_secs = 32;		}	}}intmegascsi_ioctl_init(){	int error = 0;	struct utsname uname_buf;	char delimiters[] = ".-";	char *token, cp[128], *tail;    if ( uname(&uname_buf) )return EINVAL;	strncpy(cp, uname_buf.release, 128);	token = strtok(cp, delimiters);	if ( strtol(token, &tail, 0) != 2 ) return EINVAL;	token = strtok(NULL, delimiters);	if ( strtol(token, &tail, 0) == 4 ) 		USCSICMD = 0xe0;	/* kernel 2.4.x */	else if (strtol(token, &tail, 0) == 6 ) 			USCSICMD = 0x80;	/* kernel 2.6.x */		else {			printf("This program not supported on %s\n", uname_buf.release);			return EINVAL;		}					if (!megascsi_ioctl_initialized) {			/* Initialize mega_scsi_adapter structure */		mega_scsi_adapter = malloc(sizeof(struct megascsi_adapter));		if ( mega_scsi_adapter == NULL ) {			printf("MEGA Init Failture: No memory allocation\n");			return EINVAL;		}		memset(mega_scsi_adapter, sizeof(struct megascsi_adapter), 0); 		mega_scsi_adapter->adapter_handle = open("/dev/megadev0",  O_RDONLY); 		if (mega_scsi_adapter->adapter_handle == (uint)-1) {			printf("MEGA Init failture: Can not open device file /dev/megadev0\n");			return EINVAL;		}			megascsi_adapt_no = 0;		mega_scsi_adapter->adapter_adapt_no = megascsi_adapt_no;		megascsi_ioctl_initialized = 1;	}	megascsi_query_adapt(mega_scsi_adapter);	return (error);	}intmegascsi_query_adapt(scsi_adapter)struct megascsi_adapter *scsi_adapter;{	int error = 0, i;	char *p=NULL;	struct megascsi_fc_einquiry *einq;	struct megascsi_fc_prodinfo *pi;	if ( !scsi_adapter ) return EINVAL;		/* try FC inquiry first */			p = malloc(sizeof(struct megascsi_fc_einquiry)+sizeof(struct megascsi_fc_prodinfo));	if (!p) {		printf("%s: No memory for adapter information\n",scsi_adapter->adapter_dev.dv_xname);		return EINVAL;	}	einq = (struct megascsi_fc_einquiry *)p;	pi = (struct megascsi_fc_prodinfo *)(p + sizeof(struct megascsi_fc_einquiry));	memset(einq, 0, sizeof(struct megascsi_fc_einquiry));	memset(pi, 0, sizeof(struct megascsi_fc_prodinfo));	if (megascsi_mgmt(scsi_adapter, MEGASCSI_FCOP, MEGASCSI_FC_EINQ3_SOLICITED_FULL, 0, 0, sizeof 			(struct megascsi_fc_einquiry), einq)==0) {		scsi_adapter->adapter_nunits = einq->ain_nlogdrv;		megascsi_copyhds(scsi_adapter, einq->ain_ldsize, einq->ain_ldprop,				einq->ain_ldstat);		if (megascsi_mgmt(scsi_adapter, MEGASCSI_FCOP, MEGASCSI_FC_PRODINF, 0, 0, sizeof (struct 				megascsi_fc_prodinfo), pi)==0) 			{				scsi_adapter->adapter_maxunits = MEGASCSI_BIG_MAX_LDRIVES;				memcpy(scsi_adapter->adapter_fwver, pi->api_fwver, 16);				scsi_adapter->adapter_fwver[15] = '\0';				memcpy(scsi_adapter->adapter_biosver, pi->api_biosver, 16);                                                                                                                                                                                                                                 				scsi_adapter->adapter_biosver[15] = '\0';				scsi_adapter->adapter_channels = pi->api_channels;				scsi_adapter->adapter_targets = pi->api_fcloops;				scsi_adapter->adapter_memory = letoh16(pi->api_ramsize);				scsi_adapter->adapter_maxcmds = pi->api_maxcmd;//				p = "FC loop";				}		else		{			error = EINVAL;			goto bail2;		}		if (scsi_adapter->adapter_maxunits == 0) {			struct megascsi_inquiry *inq = (struct megascsi_inquiry *)einq;			if (megascsi_mgmt(scsi_adapter, MEGASCSI_EINQUIRY, 0, 0, 0, sizeof(struct megascsi_inquiry) , inq)!=0){				if (megascsi_mgmt(scsi_adapter, MEGASCSI_INQUIRY, 0, 0, 0, sizeof(struct megascsi_inquiry), inq)!=0){					error = EINVAL;					goto bail2;				}				}			scsi_adapter->adapter_maxunits = MEGASCSI_MAX_LDRIVES;			scsi_adapter->adapter_nunits = inq->ain_nlogdrv;			megascsi_copyhds(scsi_adapter, inq->ain_ldsize, inq->ain_ldprop,			    inq->ain_ldstat);			memcpy (scsi_adapter->adapter_fwver, inq->ain_fwver, 4);			scsi_adapter->adapter_fwver[4] = '\0';			memcpy (scsi_adapter->adapter_biosver, inq->ain_biosver, 4);			scsi_adapter->adapter_biosver[4] = '\0';			scsi_adapter->adapter_channels = inq->ain_channels;			scsi_adapter->adapter_targets = inq->ain_targets;			scsi_adapter->adapter_memory = inq->ain_ramsize;			scsi_adapter->adapter_maxcmds = inq->ain_maxcmd;//			p = "target";							}	}	else	{		error = EINVAL;		goto bail2;	}/*	#ifdef MEGASCSI_DEBUG	printf(": FW %s, BIOS v%s, %dMB RAM\n"	    "%s: %d channels, %d %ss, %d logical drives, "	    "openings %d, max commands %d, quirks: %04x\n",	    scsi_adapter->adapter_fwver, scsi_adapter->adapter_biosver, scsi_adapter->adapter_memory,	    scsi_adapter->adapter_dev.dv_xname,	    scsi_adapter->adapter_channels, scsi_adapter->adapter_targets, p, scsi_adapter->adapter_nunits,	    scsi_adapter->adapter_link.openings, scsi_adapter->adapter_maxcmds, scsi_adapter->adapter_flags);#else	printf(": FW %s, BIOS v%s, %dMB RAM\n"	    "%s: %d channels, %d %ss, %d logical drives\n",	    scsi_adapter->adapter_fwver, scsi_adapter->adapter_biosver, scsi_adapter->adapter_memory,	    scsi_adapter->adapter_dev.dv_xname,	    scsi_adapter->adapter_channels, scsi_adapter->adapter_targets, p, scsi_adapter->adapter_nunits);#endif  MEGASCSI_DEBUG */	memcpy(scsi_adapter->adapter_dev.dv_xname, dv_xname, 16); 	scsi_adapter->adapter_flags |= MEGASCSI_QUARTZ;	for(i = 0; i < ((scsi_adapter->adapter_flags & MEGASCSI_QUARTZ) ?	    MEGASCSI_BIG_MAX_PDRIVES : MEGASCSI_MAX_PDRIVES); i++) {		memcpy(scsi_adapter->adapter_hdr[i].dev, scsi_adapter->adapter_dev.dv_xname, 16);	}	for(i = 0; i < MEGASCSI_MAX_CHANNEL; i++) {		memcpy(scsi_adapter->adapter_rawadapters[i].adapter_procdev, scsi_adapter->adapter_dev.dv_xname, 16);	}bail2:	if (p) free(p);	return (error);}intmegascsi_ioctl_end(){	int error = 0;	if (mega_scsi_adapter) {		if (mega_scsi_adapter->adapter_handle)			close(mega_scsi_adapter->adapter_handle);		free(mega_scsi_adapter);		megascsi_ioctl_initialized = 0;	}	else 		error = EINVAL;	return error;}int megascsi_ioctl_sel_adapt(new_adapt_no)	unsigned char new_adapt_no;{	int old_adapt_no = 0;	if (!mega_scsi_adapter) return EINVAL;	old_adapt_no = mega_scsi_adapter->adapter_adapt_no;	if ( old_adapt_no != new_adapt_no) { 		mega_scsi_adapter->adapter_adapt_no = new_adapt_no;		megascsi_query_adapt(mega_scsi_adapter);	}	megascsi_adapt_no = mega_scsi_adapter->adapter_adapt_no;			return old_adapt_no;}intmegascsi_ioctl(cmd, addr)/*	struct megascsi_adapter *scsi_adapter;*/	unsigned int cmd;	char * addr;{//	struct megascsi_adapter *scsi_adapter = (struct megascsi_adapter *)dev;	int error = 0;	switch (cmd) {	case MIOC_INQ:		error = megascsi_ioctl_inq(mega_scsi_adapter, (struct mioc_inq *)addr);		break;	case MIOC_VOL:		error = megascsi_ioctl_vol(mega_scsi_adapter, (struct mioc_vol *)addr);		break;	case MIOC_DISK:		error = megascsi_ioctl_disk(mega_scsi_adapter, (struct mioc_disk *)addr);		break;	default:		error = EINVAL;	}	return (error);}intmegascsi_drv_inq(scsi_adapter, ch, tg, page, inqbuf)	struct megascsi_adapter *scsi_adapter;	unsigned char ch;	unsigned char tg;	unsigned char page;	void *inqbuf;{	mimd_t *mimd;	struct megascsi_iocmd *cmd;	struct megascsi_passthrough *ps;	struct scsi_inquiry_data *pp;	void *idata;	int error = 0;	if (!(idata = malloc(sizeof(mimd_t) + sizeof(struct scsi_inquiry_data)))) {	    	return (ENOMEM);	}	mimd = (mimd_t *) idata;	memset(mimd, 0, sizeof *mimd);	ps = (struct megascsi_passthrough *)&(mimd->pthru);	pp = idata + sizeof *mimd;	memset(pp, 0, sizeof *pp);		mimd->ui.fcs.opcode = 0x80;	mimd->ui.fcs.adapno = 0x6d00 + scsi_adapter->adapter_adapt_no; 	mimd->outlen = sizeof(struct scsi_inquiry_data);			mimd->data = (char *)htole(pp);	cmd = (struct megascsi_iocmd *)&(mimd->mbox);	cmd->acc_cmd = MEGASCSI_PASSTHRU;	cmd->acc_passthru.apt_data = (unsigned int)htole(pp);	ps->apt_channel = ch;	ps->apt_target = tg;	ps->apt_ncdb = sizeof(struct scsi_inquiry);	ps->apt_nsense = sizeof(struct scsi_sense_data);	ps->apt_cdb[0] = INQUIRY;	ps->apt_cdb[1] = 0;	ps->apt_cdb[2] = 0;	ps->apt_cdb[3] = 0;	ps->apt_cdb[4] = sizeof(struct scsi_inquiry_data); /* INQUIRY length */	ps->apt_cdb[5] = 0;	if (page != 0) {		ps->apt_cdb[1] = SI_EVPD;		ps->apt_cdb[2] = page;	}	ps->apt_data = (unsigned int)htole(pp);	ps->apt_datalen = sizeof(struct scsi_inquiry_data);	if (ioctl(scsi_adapter->adapter_handle, USCSICMD, mimd) == 0) {		if (ps->apt_scsistat == 0x00) {			memcpy(inqbuf, pp, sizeof(struct scsi_inquiry_data));			if (pp->device != T_DIRECT)				error = EINVAL;			goto bail;		}		error = EINVAL;	}	else 		error = EINVAL;bail:	free(idata);	return (error);}intmegascsi_mgmt(scsi_adapter, opcode, par1, par2, par3, size, buffer)	struct megascsi_adapter *scsi_adapter;	unsigned char opcode;	unsigned char par1;	unsigned char par2;	unsigned char par3;	size_t size;	void *buffer;{	mimd_t *mimd;	struct megascsi_iocmd *cmd;	void *idata;	void *pa;	int error = 0;	if (!buffer) return (ENOMEM);	if (!(idata = malloc(sizeof(mimd_t)))) {	    	return (ENOMEM);	}		mimd = (mimd_t *)idata;	memset(mimd, 0, sizeof(mimd_t));	pa = buffer;	mimd->ui.fcs.opcode = 0x80;	mimd->ui.fcs.adapno = 0x6d00 + scsi_adapter->adapter_adapt_no; 	mimd->outlen = size;			mimd->data = htole(pa);	cmd = (struct megascsi_iocmd *)&(mimd->mbox);	cmd->acc_cmd = opcode;	/*	 * some commands require data to be written to idata before sending	 * command to fw	 */	switch (opcode) {	case MEGASCSI_SPEAKER:		*((char *)pa) = par1;		break;	default:		cmd->acc_io.aio_channel = par1;		cmd->acc_io.aio_param = par2;		cmd->acc_io.aio_pad[0] = par3;	};	cmd->acc_io.aio_data = (unsigned int)htole(pa);	if (ioctl(scsi_adapter->adapter_handle, USCSICMD, mimd) == 0) {		/* XXX how do commands fail? */		/* buffer = pa */		/*		if (buffer)			memcpy(buffer, pa, size);*/	}	else		error = EINVAL;	if (idata) free(idata);	return (error);}intmegascsi_ioctl_inq(scsi_adapter, bi)	struct megascsi_adapter *scsi_adapter;	struct mioc_inq *bi;{	struct megascsi_big_diskarray *p; /* struct too large for stack */	char *plist;	int i, s, t;	int off;	int error = 0;	struct scsi_inquiry_data inqbuf;	unsigned char ch, tg;	p = malloc(sizeof(struct megascsi_big_diskarray));	if (!p) {		printf("%s: no memory for disk array\n",scsi_adapter->adapter_dev.dv_xname);		return (ENOMEM);	}	memset(p, 0, sizeof(struct megascsi_big_diskarray));	plist = malloc(MEGASCSI_BIG_MAX_PDRIVES);	if (!plist) {		printf("%s: no memory for disk list\n", scsi_adapter->adapter_dev.dv_xname);		error = ENOMEM;		goto bail;	}	if (megascsi_mgmt(scsi_adapter, MEGASCSI_FCOP, MEGASCSI_FC_RDCONF, 0, 0, sizeof *p, p)) {		error = EINVAL;		goto bail2;	}	memset(plist, 0, MEGASCSI_BIG_MAX_PDRIVES);	bi->bi_novol = p->ada_nld;	bi->bi_nodisk = 0;

⌨️ 快捷键说明

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