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

📄 megaraid.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Free a SCB structure * Note: We assume the scsi commands associated with this scb is not free yet. */static voidmega_free_scb(adapter_t *adapter, scb_t *scb){	switch( scb->dma_type ) {	case MEGA_DMA_TYPE_NONE:		break;	case MEGA_SGLIST:		scsi_dma_unmap(scb->cmd);		break;	default:		break;	}	/*	 * Remove from the pending list	 */	list_del_init(&scb->list);	/* Link the scb back into free list */	scb->state = SCB_FREE;	scb->cmd = NULL;	list_add(&scb->list, &adapter->free_list);}static int__mega_busywait_mbox (adapter_t *adapter){	volatile mbox_t *mbox = adapter->mbox;	long counter;	for (counter = 0; counter < 10000; counter++) {		if (!mbox->m_in.busy)			return 0;		udelay(100);		cond_resched();	}	return -1;		/* give up after 1 second */}/* * Copies data to SGLIST * Note: For 64 bit cards, we need a minimum of one SG element for read/write */static intmega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len){	struct scatterlist *sg;	Scsi_Cmnd	*cmd;	int	sgcnt;	int	idx;	cmd = scb->cmd;	/*	 * Copy Scatter-Gather list info into controller structure.	 *	 * The number of sg elements returned must not exceed our limit	 */	sgcnt = scsi_dma_map(cmd);	scb->dma_type = MEGA_SGLIST;	BUG_ON(sgcnt > adapter->sglen || sgcnt < 0);	*len = 0;	if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) {		sg = scsi_sglist(cmd);		scb->dma_h_bulkdata = sg_dma_address(sg);		*buf = (u32)scb->dma_h_bulkdata;		*len = sg_dma_len(sg);		return 0;	}	scsi_for_each_sg(cmd, sg, sgcnt, idx) {		if (adapter->has_64bit_addr) {			scb->sgl64[idx].address = sg_dma_address(sg);			*len += scb->sgl64[idx].length = sg_dma_len(sg);		} else {			scb->sgl[idx].address = sg_dma_address(sg);			*len += scb->sgl[idx].length = sg_dma_len(sg);		}	}	/* Reset pointer and length fields */	*buf = scb->sgl_dma_addr;	/* Return count of SG requests */	return sgcnt;}/* * mega_8_to_40ld() * * takes all info in AdapterInquiry structure and puts it into ProductInfo and * Enquiry3 structures for later use */static voidmega_8_to_40ld(mraid_inquiry *inquiry, mega_inquiry3 *enquiry3,		mega_product_info *product_info){	int i;	product_info->max_commands = inquiry->adapter_info.max_commands;	enquiry3->rebuild_rate = inquiry->adapter_info.rebuild_rate;	product_info->nchannels = inquiry->adapter_info.nchannels;	for (i = 0; i < 4; i++) {		product_info->fw_version[i] =			inquiry->adapter_info.fw_version[i];		product_info->bios_version[i] =			inquiry->adapter_info.bios_version[i];	}	enquiry3->cache_flush_interval =		inquiry->adapter_info.cache_flush_interval;	product_info->dram_size = inquiry->adapter_info.dram_size;	enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;	for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {		enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];		enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];		enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];	}	for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)		enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];}static inline voidmega_free_sgl(adapter_t *adapter){	scb_t	*scb;	int	i;	for(i = 0; i < adapter->max_cmds; i++) {		scb = &adapter->scb_list[i];		if( scb->sgl64 ) {			pci_free_consistent(adapter->dev,				sizeof(mega_sgl64) * adapter->sglen,				scb->sgl64,				scb->sgl_dma_addr);			scb->sgl64 = NULL;		}		if( scb->pthru ) {			pci_free_consistent(adapter->dev, sizeof(mega_passthru),				scb->pthru, scb->pthru_dma_addr);			scb->pthru = NULL;		}		if( scb->epthru ) {			pci_free_consistent(adapter->dev,				sizeof(mega_ext_passthru),				scb->epthru, scb->epthru_dma_addr);			scb->epthru = NULL;		}	}}/* * Get information about the card/driver */const char *megaraid_info(struct Scsi_Host *host){	static char buffer[512];	adapter_t *adapter;	adapter = (adapter_t *)host->hostdata;	sprintf (buffer,		 "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",		 adapter->fw_version, adapter->product_info.max_commands,		 adapter->host->max_id, adapter->host->max_channel,		 adapter->host->max_lun);	return buffer;}/* * Abort a previous SCSI request. Only commands on the pending list can be * aborted. All the commands issued to the F/W must complete. */static intmegaraid_abort(Scsi_Cmnd *cmd){	adapter_t	*adapter;	int		rval;	adapter = (adapter_t *)cmd->device->host->hostdata;	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_ABORT);	/*	 * This is required here to complete any completed requests	 * to be communicated over to the mid layer.	 */	mega_rundoneq(adapter);	return rval;}static intmegaraid_reset(struct scsi_cmnd *cmd){	adapter_t	*adapter;	megacmd_t	mc;	int		rval;	adapter = (adapter_t *)cmd->device->host->hostdata;#if MEGA_HAVE_CLUSTERING	mc.cmd = MEGA_CLUSTER_CMD;	mc.opcode = MEGA_RESET_RESERVATIONS;	if( mega_internal_command(adapter, &mc, NULL) != 0 ) {		printk(KERN_WARNING				"megaraid: reservation reset failed.\n");	}	else {		printk(KERN_INFO "megaraid: reservation reset.\n");	}#endif	spin_lock_irq(&adapter->lock);	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);	/*	 * This is required here to complete any completed requests	 * to be communicated over to the mid layer.	 */	mega_rundoneq(adapter);	spin_unlock_irq(&adapter->lock);	return rval;}/** * megaraid_abort_and_reset() * @adapter - megaraid soft state * @cmd - scsi command to be aborted or reset * @aor - abort or reset flag * * Try to locate the scsi command in the pending queue. If found and is not * issued to the controller, abort/reset it. Otherwise return failure */static intmegaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor){	struct list_head	*pos, *next;	scb_t			*scb;	printk(KERN_WARNING "megaraid: %s-%lx cmd=%x <c=%d t=%d l=%d>\n",	     (aor == SCB_ABORT)? "ABORTING":"RESET", cmd->serial_number,	     cmd->cmnd[0], cmd->device->channel, 	     cmd->device->id, cmd->device->lun);	if(list_empty(&adapter->pending_list))		return FALSE;	list_for_each_safe(pos, next, &adapter->pending_list) {		scb = list_entry(pos, scb_t, list);		if (scb->cmd == cmd) { /* Found command */			scb->state |= aor;			/*			 * Check if this command has firmare owenership. If			 * yes, we cannot reset this command. Whenever, f/w			 * completes this command, we will return appropriate			 * status from ISR.			 */			if( scb->state & SCB_ISSUED ) {				printk(KERN_WARNING					"megaraid: %s-%lx[%x], fw owner.\n",					(aor==SCB_ABORT) ? "ABORTING":"RESET",					cmd->serial_number, scb->idx);				return FALSE;			}			else {				/*				 * Not yet issued! Remove from the pending				 * list				 */				printk(KERN_WARNING					"megaraid: %s-%lx[%x], driver owner.\n",					(aor==SCB_ABORT) ? "ABORTING":"RESET",					cmd->serial_number, scb->idx);				mega_free_scb(adapter, scb);				if( aor == SCB_ABORT ) {					cmd->result = (DID_ABORT << 16);				}				else {					cmd->result = (DID_RESET << 16);				}				list_add_tail(SCSI_LIST(cmd),						&adapter->completed_list);				return TRUE;			}		}	}	return FALSE;}static inline intmake_local_pdev(adapter_t *adapter, struct pci_dev **pdev){	*pdev = alloc_pci_dev();	if( *pdev == NULL ) return -1;	memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));	if( pci_set_dma_mask(*pdev, DMA_32BIT_MASK) != 0 ) {		kfree(*pdev);		return -1;	}	return 0;}static inline voidfree_local_pdev(struct pci_dev *pdev){	kfree(pdev);}/** * mega_allocate_inquiry() * @dma_handle - handle returned for dma address * @pdev - handle to pci device * * allocates memory for inquiry structure */static inline void *mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev){	return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle);}static inline voidmega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev){	pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle);}#ifdef CONFIG_PROC_FS/* Following code handles /proc fs  */#define CREATE_READ_PROC(string, func)	create_proc_read_entry(string,	\					S_IRUSR | S_IFREG,		\					controller_proc_dir_entry,	\					func, adapter)/** * mega_create_proc_entry() * @index - index in soft state array * @parent - parent node for this /proc entry * * Creates /proc entries for our controllers. */static voidmega_create_proc_entry(int index, struct proc_dir_entry *parent){	struct proc_dir_entry	*controller_proc_dir_entry = NULL;	u8		string[64] = { 0 };	adapter_t	*adapter = hba_soft_state[index];	sprintf(string, "hba%d", adapter->host->host_no);	controller_proc_dir_entry =		adapter->controller_proc_dir_entry = proc_mkdir(string, parent);	if(!controller_proc_dir_entry) {		printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n");		return;	}	adapter->proc_read = CREATE_READ_PROC("config", proc_read_config);	adapter->proc_stat = CREATE_READ_PROC("stat", proc_read_stat);	adapter->proc_mbox = CREATE_READ_PROC("mailbox", proc_read_mbox);#if MEGA_HAVE_ENH_PROC	adapter->proc_rr = CREATE_READ_PROC("rebuild-rate", proc_rebuild_rate);	adapter->proc_battery = CREATE_READ_PROC("battery-status",			proc_battery);	/*	 * Display each physical drive on its channel	 */	adapter->proc_pdrvstat[0] = CREATE_READ_PROC("diskdrives-ch0",					proc_pdrv_ch0);	adapter->proc_pdrvstat[1] = CREATE_READ_PROC("diskdrives-ch1",					proc_pdrv_ch1);	adapter->proc_pdrvstat[2] = CREATE_READ_PROC("diskdrives-ch2",					proc_pdrv_ch2);	adapter->proc_pdrvstat[3] = CREATE_READ_PROC("diskdrives-ch3",					proc_pdrv_ch3);	/*	 * Display a set of up to 10 logical drive through each of following	 * /proc entries	 */	adapter->proc_rdrvstat[0] = CREATE_READ_PROC("raiddrives-0-9",					proc_rdrv_10);	adapter->proc_rdrvstat[1] = CREATE_READ_PROC("raiddrives-10-19",					proc_rdrv_20);	adapter->proc_rdrvstat[2] = CREATE_READ_PROC("raiddrives-20-29",					proc_rdrv_30);	adapter->proc_rdrvstat[3] = CREATE_READ_PROC("raiddrives-30-39",					proc_rdrv_40);#endif}/** * proc_read_config() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display configuration information about the controller. */static intproc_read_config(char *page, char **start, off_t offset, int count, int *eof,		void *data){	adapter_t *adapter = (adapter_t *)data;	int len = 0;	len += sprintf(page+len, "%s", MEGARAID_VERSION);	if(adapter->product_info.product_name[0])		len += sprintf(page+len, "%s\n",				adapter->product_info.product_name);	len += sprintf(page+len, "Controller Type: ");	if( adapter->flag & BOARD_MEMMAP ) {		len += sprintf(page+len,			"438/466/467/471/493/518/520/531/532\n");	}	else {		len += sprintf(page+len,			"418/428/434\n");	}	if(adapter->flag & BOARD_40LD) {		len += sprintf(page+len,				"Controller Supports 40 Logical Drives\n");	}	if(adapter->flag & BOARD_64BIT) {		len += sprintf(page+len,		"Controller capable of 64-bit memory addressing\n");	}	if( adapter->has_64bit_addr ) {		len += sprintf(page+len,			"Controller using 64-bit memory addressing\n");	}	else {		len += sprintf(page+len,			"Controller is not using 64-bit memory addressing\n");	}	len += sprintf(page+len, "Base = %08lx, Irq = %d, ", adapter->base,			adapter->host->irq);	len += sprintf(page+len, "Logical Drives = %d, Channels = %d\n",			adapter->numldrv, adapter->product_info.nchannels);	len += sprintf(page+len, "Version =%s:%s, DRAM = %dMb\n",			adapter->fw_version, adapter->bios_version,			adapter->product_info.dram_size);	len += sprintf(page+len,		"Controller Queue Depth = %d, Driver Queue Depth = %d\n",		adapter->product_info.max_commands, adapter->max_cmds);	len += sprintf(page+len, "support_ext_cdb    = %d\n",			adapter->support_ext_cdb);	len += sprintf(page+len, "support_random_del = %d\n",			adapter->support_random_del);	len += sprintf(page+len, "boot_ldrv_enabled  = %d\n",			adapter->boot_ldrv_enabled);	len += sprintf(page+len, "boot_ldrv          = %d\n",			adapter->boot_ldrv);	len += sprintf(page+len, "boot_pdrv_enabled  = %d\n",			adapter->boot_pdrv_enabled);	len += sprintf(page+len, "boot_pdrv_ch       = %d\n",			adapter->boot_pdrv_ch);	len += sprintf(page+len, "boot_pdrv_tgt      = %d\n",			adapter->boot_pdrv_tgt);	len += sprintf(page+len, "quiescent          = %d\n",			atomic_read(&adapter->quiescent));	len += sprintf(page+len, "has_cluster        = %d\n",			adapter->has_cluster);	len += sprintf(page+len, "\nModule Parameters:\n");	len += sprintf(page+len, "max_cmd_per_lun    = %d\n",			max_cmd_per_lun);	len += sprintf(page+len, "max_sectors_per_io = %d\n",			max_sectors_per_io);	*eof = 1;	return len;}/** * proc_read_stat() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Diaplay statistical information about the I/O activity. */static intproc_read_stat(char *page, char **start, off_t offset, int count, int *eof,		void *data){	adapter_t	*adapter;

⌨️ 快捷键说明

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