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

📄 dpt_i2o.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
						return -ENOMEM;					}					pHba->channel[bus_no].device[scsi_id] = pDev;					memset(pDev,0,sizeof(struct adpt_device));				} else {					for( pDev = pHba->channel[bus_no].device[scsi_id];								pDev->next_lun; pDev = pDev->next_lun){					}					pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);					if(pDev == NULL) {						return -ENOMEM;					}					memset(pDev->next_lun,0,sizeof(struct adpt_device));					pDev = pDev->next_lun;				}				pDev->tid = tid;				pDev->scsi_channel = bus_no;				pDev->scsi_id = scsi_id;				pDev->scsi_lun = scsi_lun;				pDev->pI2o_dev = d;				d->owner = pDev;				pDev->type = (buf[0])&0xff;				pDev->flags = (buf[0]>>8)&0xff;				if(scsi_id > pHba->top_scsi_id){					pHba->top_scsi_id = scsi_id;				}				if(scsi_lun > pHba->top_scsi_lun){					pHba->top_scsi_lun = scsi_lun;				}			}			if(scsi_id == -1){				printk(KERN_WARNING"Could not find SCSI ID for %s\n",						d->lct_data.identity_tag);			}		}	}	return 0;}/* *	Each I2O controller has a chain of devices on it - these match *	the useful parts of the LCT of the board. */ static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d){	down(&adpt_configuration_lock);	d->controller=pHba;	d->owner=NULL;	d->next=pHba->devices;	d->prev=NULL;	if (pHba->devices != NULL){		pHba->devices->prev=d;	}	pHba->devices=d;	*d->dev_name = 0;	up(&adpt_configuration_lock);	return 0;}static int adpt_open(struct inode *inode, struct file *file){	int minor;	adpt_hba* pHba;	//TODO check for root access	//	minor = MINOR(inode->i_rdev);	if (minor >= hba_count) {		return -ENXIO;	}	down(&adpt_configuration_lock);	for (pHba = hba_chain; pHba; pHba = pHba->next) {		if (pHba->unit == minor) {			break;	/* found adapter */		}	}	if (pHba == NULL) {		up(&adpt_configuration_lock);		return -ENXIO;	}//	if(pHba->in_use){	//	up(&adpt_configuration_lock);//		return -EBUSY;//	}	pHba->in_use = 1;	up(&adpt_configuration_lock);	return 0;}static int adpt_close(struct inode *inode, struct file *file){	int minor;	adpt_hba* pHba;	minor = MINOR(inode->i_rdev);	if (minor >= hba_count) {		return -ENXIO;	}	down(&adpt_configuration_lock);	for (pHba = hba_chain; pHba; pHba = pHba->next) {		if (pHba->unit == minor) {			break;	/* found adapter */		}	}	up(&adpt_configuration_lock);	if (pHba == NULL) {		return -ENXIO;	}	pHba->in_use = 0;	return 0;}static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg){	u32 msg[MAX_MESSAGE_SIZE];	u32* reply = NULL;	u32 size = 0;	u32 reply_size = 0;	u32* user_msg = (u32*)arg;	u32* user_reply = NULL;	ulong sg_list[pHba->sg_tablesize];	u32 sg_offset = 0;	u32 sg_count = 0;	int sg_index = 0;	u32 i = 0;	u32 rcode = 0;	ulong p = 0;	ulong flags = 0;	memset(&msg, 0, MAX_MESSAGE_SIZE*4);	// get user msg size in u32s 	if(get_user(size, &user_msg[0])){		return -EFAULT;	}	size = size>>16;	user_reply = &user_msg[size];	if(size > MAX_MESSAGE_SIZE){		return -EFAULT;	}	size *= 4; // Convert to bytes	/* Copy in the user's I2O command */	if(copy_from_user((void*)msg, (void*)user_msg, size)) {		return -EFAULT;	}	get_user(reply_size, &user_reply[0]);	reply_size = reply_size>>16;	if(reply_size > REPLY_FRAME_SIZE){		reply_size = REPLY_FRAME_SIZE;	}	reply_size *= 4;	reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);	if(reply == NULL) {		printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);		return -ENOMEM;	}	memset(reply,0,REPLY_FRAME_SIZE*4);	sg_offset = (msg[0]>>4)&0xf;	msg[2] = 0x40000000; // IOCTL context	msg[3] = (u32)reply;	memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);	if(sg_offset) {		// TODO 64bit fix		struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);		if (sg_count > pHba->sg_tablesize){			printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);			kfree (reply);			return -EINVAL;		}		for(i = 0; i < sg_count; i++) {			int sg_size;			if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {				printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);				rcode = -EINVAL;				goto cleanup;			}			sg_size = sg[i].flag_count & 0xffffff;      			/* Allocate memory for the transfer */			p = (ulong)kmalloc(sg_size, GFP_KERNEL|ADDR32);			if(p == 0) {				printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",						pHba->name,sg_size,i,sg_count);				rcode = -ENOMEM;				goto cleanup;			}			sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.			/* Copy in the user's SG buffer if necessary */			if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {				// TODO 64bit fix				if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) {					printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);					rcode = -EFAULT;					goto cleanup;				}			}			//TODO 64bit fix			sg[i].addr_bus = (u32)virt_to_bus((void*)p);		}	}	do {		spin_lock_irqsave(&io_request_lock, flags);		// This state stops any new commands from enterring the		// controller while processing the ioctl//		pHba->state |= DPTI_STATE_IOCTL;//		We can't set this now - The scsi subsystem sets host_blocked and//		the queue empties and stops.  We need a way to restart the queue		rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);//		pHba->state &= ~DPTI_STATE_IOCTL;		spin_unlock_irqrestore(&io_request_lock, flags);	} while(rcode == -ETIMEDOUT);  	if(rcode){		goto cleanup;	}	if(sg_offset) {	/* Copy back the Scatter Gather buffers back to user space */		u32 j;		// TODO 64bit fix		struct sg_simple_element* sg;		int sg_size;		// re-acquire the original message to handle correctly the sg copy operation		memset(&msg, 0, MAX_MESSAGE_SIZE*4); 		// get user msg size in u32s 		if(get_user(size, &user_msg[0])){			rcode = -EFAULT; 			goto cleanup; 		}		size = size>>16;		size *= 4;		/* Copy in the user's I2O command */		if (copy_from_user ((void*)msg, (void*)user_msg, size)) {			rcode = -EFAULT;			goto cleanup;		}		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);		// TODO 64bit fix		sg 	 = (struct sg_simple_element*)(msg + sg_offset);		for (j = 0; j < sg_count; j++) {			/* Copy out the SG list to user's buffer if necessary */			if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {				sg_size = sg[j].flag_count & 0xffffff; 				// TODO 64bit fix				if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {					printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);					rcode = -EFAULT;					goto cleanup;				}			}		}	} 	/* Copy back the reply to user space */	if (reply_size) {		// we wrote our own values for context - now restore the user supplied ones		if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {			printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);			rcode = -EFAULT;		}		if(copy_to_user(user_reply, reply, reply_size)) {			printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);			rcode = -EFAULT;		}	}cleanup:	kfree (reply);	while(sg_index) {		if(sg_list[--sg_index]) {			kfree((void*)(sg_list[sg_index]));		}	}	return rcode;}/* * This routine returns information about the system.  This does not effect * any logic and if the info is wrong - it doesn't matter. *//* Get all the info we can not get from kernel services */static int adpt_system_info(void *buffer){	sysInfo_S si;	memset(&si, 0, sizeof(si));	si.osType = OS_LINUX;	si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);	si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);	si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);	si.busType = SI_PCI_BUS;	si.processorFamily = DPTI_sig.dsProcessorFamily;#if defined __i386__ 	adpt_i386_info(&si);#elif defined (__ia64__)	adpt_ia64_info(&si);#elif defined(__sparc__)	adpt_sparc_info(&si);#elif defined (__alpha__)	adpt_alpha_info(&si);#else	si.processorType = 0xff ;#endif	if(copy_to_user(buffer, &si, sizeof(si))){		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");		return -EFAULT;	}	return 0;}#if defined __ia64__ static void adpt_ia64_info(sysInfo_S* si){	// This is all the info we need for now	// We will add more info as our new	// managmenent utility requires it	si->processorType = PROC_IA64;}#endif#if defined __sparc__ static void adpt_sparc_info(sysInfo_S* si){	// This is all the info we need for now	// We will add more info as our new	// managmenent utility requires it	si->processorType = PROC_ULTRASPARC;}#endif#if defined __alpha__ static void adpt_alpha_info(sysInfo_S* si){	// This is all the info we need for now	// We will add more info as our new	// managmenent utility requires it	si->processorType = PROC_ALPHA;}#endif#if defined __i386__static void adpt_i386_info(sysInfo_S* si){	// This is all the info we need for now	// We will add more info as our new	// managmenent utility requires it	switch (boot_cpu_data.x86) {	case CPU_386:		si->processorType = PROC_386;		break;	case CPU_486:		si->processorType = PROC_486;		break;	case CPU_586:		si->processorType = PROC_PENTIUM;		break;	default:  // Just in case 		si->processorType = PROC_PENTIUM;		break;	}}#endifstatic int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,	      ulong arg){	int minor;	int error = 0;	adpt_hba* pHba;	ulong flags;	minor = MINOR(inode->i_rdev);	if (minor >= DPTI_MAX_HBA){		return -ENXIO;	}	down(&adpt_configuration_lock);	for (pHba = hba_chain; pHba; pHba = pHba->next) {		if (pHba->unit == minor) {			break;	/* found adapter */		}	}	up(&adpt_configuration_lock);	if(pHba == NULL){		return -ENXIO;	}	while((volatile u32) pHba->state & DPTI_STATE_RESET ) {		set_task_state(current,TASK_UNINTERRUPTIBLE);		schedule_timeout(2);	}	switch (cmd) {	// TODO: handle 3 cases	case DPT_SIGNATURE:		if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {			return -EFAULT;		}		break;	case I2OUSRCMD:		return	adpt_i2o_passthru(pHba,(u32*)arg);		break;	case DPT_CTRLINFO:{		drvrHBAinfo_S HbaInfo;#define FLG_OSD_PCI_VALID 0x0001#define FLG_OSD_DMA	  0x0002#define FLG_OSD_I2O	  0x0004		memset(&HbaInfo, 0, sizeof(HbaInfo));		HbaInfo.drvrHBAnum = pHba->unit;		HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;		HbaInfo.blinkState = adpt_read_blink_led(pHba);		HbaInfo.pciBusNum =  pHba->pDev->bus->number;		HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn); 		HbaInfo.Interrupt = pHba->pDev->irq; 		HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;		if(copy_to_user((void *) arg, &HbaInfo, sizeof(HbaInfo))){			printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);			return -EFAULT;		}		break;		}	case DPT_SYSINFO:		return adpt_system_info((void*)arg);		break;	case DPT_BLINKLED:{		u32 value;		value = (u32)adpt_read_blink_led(pHba);		if (copy_to_user((char*)arg, &value, sizeof(value))) {			return -EFAULT;		}		break;		}	case I2ORESETCMD:		spin_lock_irqsave(&io_request_lock, flags);		adpt_hba_reset(pHba);		spin_unlock_irqrestore(&io_request_lock, flags);		break;	case I2ORESCANCMD:		adpt_rescan(pHba);		break;	case DPT_TARGET_BUSY & 0xFFFF:	case DPT_TARGET_BUSY:	{		TARGET_BUSY_T busy;		struct adpt_device* d;		if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {			return -EFAULT;		}		d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);		if(d == NULL){			return -ENODEV;		}		busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;		if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {			return -EFAULT;		}		break;	}	default:		return -EINVAL;	}	return error;}static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs){	Scsi_Cmnd* cmd;

⌨️ 快捷键说明

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