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

📄 dpt_i2o.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	geom[2] = cylinders;		PDEBUG("adpt_bios_param: exit\n");	return 0;}static const char *adpt_info(struct Scsi_Host *host){	adpt_hba* pHba;	pHba = (adpt_hba *) host->hostdata[0];	return (char *) (pHba->detail);}static int adpt_proc_info(char *buffer, char **start, off_t offset,		  int length, int hostno, int inout){	struct adpt_device* d;	int id;	int chan;	int len = 0;	int begin = 0;	int pos = 0;	adpt_hba* pHba;	struct Scsi_Host *host;	int unit;	*start = buffer;	if (inout == TRUE) {		/*		 * The user has done a write and wants us to take the		 * data in the buffer and do something with it.		 * proc_scsiwrite calls us with inout = 1		 *		 * Read data from buffer (writing to us) - NOT SUPPORTED		 */		return -EINVAL;	}	/*	 * inout = 0 means the user has done a read and wants information	 * returned, so we write information about the cards into the buffer	 * proc_scsiread() calls us with inout = 0	 */	// Find HBA (host bus adapter) we are looking for	down(&adpt_configuration_lock);	for (pHba = hba_chain; pHba; pHba = pHba->next) {		if (pHba->host->host_no == hostno) {			break;	/* found adapter */		}	}	up(&adpt_configuration_lock);	if (pHba == NULL) {		return 0;	}	host = pHba->host;	len  = sprintf(buffer    , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);	len += sprintf(buffer+len, "%s\n", pHba->detail);	len += sprintf(buffer+len, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 			pHba->host->host_no, pHba->name, host->irq);	len += sprintf(buffer+len, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",			host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);	pos = begin + len;	/* CHECKPOINT */	if(pos > offset + length) {		goto stop_output;	}	if(pos <= offset) {		/*		 * If we haven't even written to where we last left		 * off (the last time we were called), reset the 		 * beginning pointer.		 */		len = 0;		begin = pos;	}	len +=  sprintf(buffer+len, "Devices:\n");	for(chan = 0; chan < MAX_CHANNEL; chan++) {		for(id = 0; id < MAX_ID; id++) {			d = pHba->channel[chan].device[id];			while(d){				len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);				len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);				pos = begin + len;				/* CHECKPOINT */				if(pos > offset + length) {					goto stop_output;				}				if(pos <= offset) {					len = 0;					begin = pos;				}				unit = d->pI2o_dev->lct_data.tid;				len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d)  (%s)\n\n",					       unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,					       d->pScsi_dev->online? "online":"offline"); 				pos = begin + len;				/* CHECKPOINT */				if(pos > offset + length) {					goto stop_output;				}				if(pos <= offset) {					len = 0;					begin = pos;				}				d = d->next_lun;			}		}	}	/*	 * begin is where we last checked our position with regards to offset	 * begin is always less than offset.  len is relative to begin.  It	 * is the number of bytes written past begin	 *	 */stop_output:	/* stop the output and calculate the correct length */	*(buffer + len) = '\0';	*start = buffer + (offset - begin);	/* Start of wanted data */	len -= (offset - begin);	if(len > length) {		len = length;	} else if(len < 0){		len = 0;		**start = '\0';	}	return len;}/*=========================================================================== * Error Handling routines *=========================================================================== */static int adpt_abort(Scsi_Cmnd * cmd){	adpt_hba* pHba = NULL;	/* host bus adapter structure */	struct adpt_device* dptdevice;	/* dpt per device information */	u32 msg[5];	int rcode;	if(cmd->serial_number == 0){		return FAILED;	}	pHba = (adpt_hba*) cmd->host->hostdata[0];	printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);	if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {		printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);		return FAILED;	}	memset(msg, 0, sizeof(msg));	msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;	msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;	msg[2] = 0;	msg[3]= 0; 	msg[4] = (u32)cmd;	if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){		if(rcode == -EOPNOTSUPP ){			printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);			return FAILED;		}		printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);		return FAILED;	} 	printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);	return SUCCESS;}#define I2O_DEVICE_RESET 0x27// This is the same for BLK and SCSI devices// NOTE this is wrong in the i2o.h definitions// This is not currently supported by our adapter but we issue it anywaystatic int adpt_device_reset(Scsi_Cmnd* cmd){	adpt_hba* pHba;	u32 msg[4];	u32 rcode;	int old_state;	struct adpt_device* d = (void*) cmd->device->hostdata;	pHba = (void*) cmd->host->hostdata[0];	printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);	if (!d) {		printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);		return FAILED;	}	memset(msg, 0, sizeof(msg));	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;	msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);	msg[2] = 0;	msg[3] = 0;	old_state = d->state;	d->state |= DPTI_DEV_RESET;	if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){		d->state = old_state;		if(rcode == -EOPNOTSUPP ){			printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);			return FAILED;		}		printk(KERN_INFO"%s: Device reset failed\n",pHba->name);		return FAILED;	} else {		d->state = old_state;		printk(KERN_INFO"%s: Device reset successful\n",pHba->name);		return SUCCESS;	}}#define I2O_HBA_BUS_RESET 0x87// This version of bus reset is called by the eh_error handlerstatic int adpt_bus_reset(Scsi_Cmnd* cmd){	adpt_hba* pHba;	u32 msg[4];	pHba = (adpt_hba*)cmd->host->hostdata[0];	memset(msg, 0, sizeof(msg));	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid );	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);	msg[2] = 0;	msg[3] = 0;	if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){		printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);		return FAILED;	} else {		printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);		return SUCCESS;	}}// This version of reset is called by the eh_error_handlerstatic int adpt_reset(Scsi_Cmnd* cmd){	adpt_hba* pHba;	int rcode;	pHba = (adpt_hba*)cmd->host->hostdata[0];	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid );	rcode =  adpt_hba_reset(pHba);	if(rcode == 0){		printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);		return SUCCESS;	} else {		printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);		return FAILED;	}}// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_resetstatic int adpt_hba_reset(adpt_hba* pHba){	int rcode;	pHba->state |= DPTI_STATE_RESET;	// Activate does get status , init outbound, and get hrt	if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {		printk(KERN_ERR "%s: Could not activate\n", pHba->name);		adpt_i2o_delete_hba(pHba);		return rcode;	}	if ((rcode=adpt_i2o_build_sys_table()) < 0) {		adpt_i2o_delete_hba(pHba);		return rcode;	}	PDEBUG("%s: in HOLD state\n",pHba->name);	if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {		adpt_i2o_delete_hba(pHba);			return rcode;	}	PDEBUG("%s: in OPERATIONAL state\n",pHba->name);	if ((rcode=adpt_i2o_lct_get(pHba)) < 0){		adpt_i2o_delete_hba(pHba);		return rcode;	}	if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){		adpt_i2o_delete_hba(pHba);		return rcode;	}	pHba->state &= ~DPTI_STATE_RESET;	adpt_fail_posted_scbs(pHba);	return 0;	/* return success */}/*=========================================================================== *  *=========================================================================== */static void adpt_i2o_sys_shutdown(void){	adpt_hba *pHba, *pNext;	struct adpt_i2o_post_wait_data *p1, *p2;	 printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");	 printk(KERN_INFO"   This could take a few minutes if there are many devices attached\n");	/* Delete all IOPs from the controller chain */	/* They should have already been released by the	 * scsi-core	 */	for (pHba = hba_chain; pHba; pHba = pNext) {		pNext = pHba->next;		adpt_i2o_delete_hba(pHba);	}	/* Remove any timedout entries from the wait queue.  */	p2 = NULL;//	spin_lock_irqsave(&adpt_post_wait_lock, flags);	/* Nothing should be outstanding at this point so just	 * free them 	 */	for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {		kfree(p1);	}//	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);	adpt_post_wait_queue = 0;	 printk(KERN_INFO "Adaptec I2O controllers down.\n");}/* * reboot/shutdown notification. * * - Quiesce each IOP in the system * */#ifdef REBOOT_NOTIFIERstatic int adpt_reboot_event(struct notifier_block *n, ulong code, void *p){	 if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)		  return NOTIFY_DONE;	 adpt_i2o_sys_shutdown();	 return NOTIFY_DONE;}#endifstatic int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) {	adpt_hba* pHba = NULL;	adpt_hba* p = NULL;	ulong base_addr0_phys = 0;	ulong base_addr1_phys = 0;	u32 hba_map0_area_size = 0;	u32 hba_map1_area_size = 0;	ulong base_addr_virt = 0;	ulong msg_addr_virt = 0;	int raptorFlag = FALSE;	int i;	if(pci_enable_device(pDev)) {		return -EINVAL;	}	pci_set_master(pDev);	base_addr0_phys = pci_resource_start(pDev,0);	hba_map0_area_size = pci_resource_len(pDev,0);	// Check if standard PCI card or single BAR Raptor	if(pDev->device == PCI_DPT_DEVICE_ID){		if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){			// Raptor card with this device id needs 4M			hba_map0_area_size = 0x400000;		} else { // Not Raptor - it is a PCI card			if(hba_map0_area_size > 0x100000 ){ 				hba_map0_area_size = 0x100000;			}		}	} else {// Raptor split BAR config		// Use BAR1 in this configuration		base_addr1_phys = pci_resource_start(pDev,1);		hba_map1_area_size = pci_resource_len(pDev,1);		raptorFlag = TRUE;	}	base_addr_virt = (ulong)ioremap(base_addr0_phys,hba_map0_area_size);	if(base_addr_virt == 0) {		PERROR("dpti: adpt_config_hba: io remap failed\n");		return -EINVAL;	}        if(raptorFlag == TRUE) {		msg_addr_virt = (ulong)ioremap(base_addr1_phys, hba_map1_area_size );		if(msg_addr_virt == 0) {			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");			iounmap((void*)base_addr_virt);			return -EINVAL;		}	} else {		msg_addr_virt = base_addr_virt;	}		// Allocate and zero the data structure	pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);	if( pHba == NULL) {		if(msg_addr_virt != base_addr_virt){			iounmap((void*)msg_addr_virt);		}		iounmap((void*)base_addr_virt);		return -ENOMEM;	}	memset(pHba, 0, sizeof(adpt_hba));	down(&adpt_configuration_lock);	for(i=0;i<DPTI_MAX_HBA;i++) {		if(hbas[i]==NULL) {			hbas[i]=pHba;			break;		}	}	if(hba_chain != NULL){		for(p = hba_chain; p->next; p = p->next);		p->next = pHba;	} else {		hba_chain = pHba;	}	pHba->next = NULL;	pHba->unit = hba_count;	sprintf(pHba->name, "dpti%d", i);	hba_count++;		up(&adpt_configuration_lock);	pHba->pDev = pDev;	pHba->base_addr_phys = base_addr0_phys;	// Set up the Virtual Base Address of the I2O Device	pHba->base_addr_virt = base_addr_virt;	pHba->msg_addr_virt = msg_addr_virt;  	pHba->irq_mask = (ulong)(base_addr_virt+0x30);	pHba->post_port = (ulong)(base_addr_virt+0x40);	pHba->reply_port = (ulong)(base_addr_virt+0x44);	pHba->hrt = NULL;	pHba->lct = NULL;	pHba->lct_size = 0;	pHba->status_block = NULL;	pHba->post_count = 0;	pHba->state = DPTI_STATE_RESET;	pHba->pDev = pDev;	pHba->devices = NULL;	// Initializing the spinlocks	spin_lock_init(&pHba->state_lock);	if(raptorFlag == 0){		printk(KERN_INFO"Adaptec I2O RAID controller %d at %lx size=%x irq=%d\n", 			hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);	} else {		printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);		printk(KERN_INFO"     BAR0 %lx - size= %x\n",base_addr_virt,hba_map0_area_size);		printk(KERN_INFO"     BAR1 %lx - size= %x\n",msg_addr_virt,hba_map1_area_size);	}	if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {		printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);		adpt_i2o_delete_hba(pHba);		return -EINVAL;	}	return 0;}static void adpt_i2o_delete_hba(adpt_hba* pHba){	adpt_hba* p1;

⌨️ 快捷键说明

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