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

📄 qla1280.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * the bytes would be pairwise reversed.  Since most of the	 * firmware quantites are, in fact, bytes, we do an extra	 * le16_to_cpu() in the firmware read routine.	 *	 * The upshot of all this is that the bytes in the firmware	 * are in the correct places, but the 16 and 32 bit quantites	 * are still in little endian format.  We fix that up below by	 * doing extra reverses on them */	nv->isp_parameter = cpu_to_le16(nv->isp_parameter);	nv->firmware_feature.w = cpu_to_le16(nv->firmware_feature.w);	for(i = 0; i < MAX_BUSES; i++) {		nv->bus[i].selection_timeout = cpu_to_le16(nv->bus[i].selection_timeout);		nv->bus[i].max_queue_depth = cpu_to_le16(nv->bus[i].max_queue_depth);	}	dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n");	LEAVE("qla1280_read_nvram");	return chksum;}/************************************************************************** *   qla1280_info *     Return a string describing the driver. **************************************************************************/static const char *qla1280_info(struct Scsi_Host *host){	static char qla1280_scsi_name_buffer[125];	char *bp;	struct scsi_qla_host *ha;	struct qla_boards *bdp;	bp = &qla1280_scsi_name_buffer[0];	ha = (struct scsi_qla_host *)host->hostdata;	bdp = &ql1280_board_tbl[ha->devnum];	memset(bp, 0, sizeof(qla1280_scsi_name_buffer));	sprintf (bp,		 "QLogic %s PCI to SCSI Host Adapter\n"		 "       Firmware version: %2d.%02d.%02d, Driver version %s",		 &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],		 QLA1280_VERSION);	return bp;}/************************************************************************** *   qla1200_queuecommand *     Queue a command to the controller. * * Note: * The mid-level driver tries to ensures that queuecommand never gets invoked * concurrently with itself or the interrupt handler (although the * interrupt handler may call this routine as part of request-completion * handling).   Unfortunely, it sometimes calls the scheduler in interrupt * context which is a big NO! NO!. **************************************************************************/static intqla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)){	struct Scsi_Host *host = cmd->device->host;	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;	struct srb *sp = (struct srb *)&cmd->SCp;	int status;	cmd->scsi_done = fn;	sp->cmd = cmd;	sp->flags = 0;	qla1280_print_scsi_cmd(5, cmd);#ifdef QLA_64BIT_PTR	/*	 * Using 64 bit commands if the PCI bridge doesn't support it is a	 * bit wasteful, however this should really only happen if one's	 * PCI controller is completely broken, like the BCM1250. For	 * sane hardware this is not an issue.	 */	status = qla1280_64bit_start_scsi(ha, sp);#else	status = qla1280_32bit_start_scsi(ha, sp);#endif	return status;}enum action {	ABORT_COMMAND,	ABORT_DEVICE,	DEVICE_RESET,	BUS_RESET,	ADAPTER_RESET,	FAIL};/* timer action for error action processor */static void qla1280_error_wait_timeout(unsigned long __data){	struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data;	struct srb *sp = (struct srb *)CMD_SP(cmd);	complete(sp->wait);}static void qla1280_mailbox_timeout(unsigned long __data){	struct scsi_qla_host *ha = (struct scsi_qla_host *)__data;	struct device_reg *reg;	reg = ha->iobase;	ha->mailbox_out[0] = RD_REG_WORD(&reg->mailbox0);	printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, "	       "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0],	       RD_REG_WORD(&reg->ictrl), RD_REG_WORD(&reg->istatus));	complete(ha->mailbox_wait);}/************************************************************************** * qla1200_error_action *    The function will attempt to perform a specified error action and *    wait for the results (or time out). * * Input: *      cmd = Linux SCSI command packet of the command that cause the *            bus reset. *      action = error action to take (see action_t) * * Returns: *      SUCCESS or FAILED * * Note: *      Resetting the bus always succeeds - is has to, otherwise the *      kernel will panic! Try a surgical technique - sending a BUS *      DEVICE RESET message - on the offending target before pulling *      the SCSI bus reset line. **************************************************************************/static intqla1280_error_action(struct scsi_cmnd *cmd, enum action action){	struct scsi_qla_host *ha;	int bus, target, lun;	struct srb *sp;	uint16_t data;	unsigned char *handle;	int result, i;	DECLARE_COMPLETION(wait);	struct timer_list timer;	ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata);	dprintk(4, "error_action %i, istatus 0x%04x\n", action,		RD_REG_WORD(&ha->iobase->istatus));	dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n",		RD_REG_WORD(&ha->iobase->host_cmd),		RD_REG_WORD(&ha->iobase->ictrl), jiffies);	ENTER("qla1280_error_action");	if (qla1280_verbose)		printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, "		       "Handle=0x%p, action=0x%x\n",		       ha->host_no, cmd, CMD_HANDLE(cmd), action);	if (cmd == NULL) {		printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL "		       "si_Cmnd pointer, failing.\n");		LEAVE("qla1280_error_action");		return FAILED;	}	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;	sp = (struct srb *)CMD_SP(cmd);	handle = CMD_HANDLE(cmd);	/* Check for pending interrupts. */	data = qla1280_debounce_register(&ha->iobase->istatus);	/*	 * The io_request_lock is held when the reset handler is called, hence	 * the interrupt handler cannot be running in parallel as it also	 * grabs the lock. /Jes	 */	if (data & RISC_INT)		qla1280_isr(ha, &ha->done_q);	/*	 * Determine the suggested action that the mid-level driver wants	 * us to perform.	 */	if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) {		if(action == ABORT_COMMAND) {			/* we never got this command */			printk(KERN_INFO "qla1280: Aborting a NULL handle\n");			return SUCCESS;	/* no action - we don't have command */		}	} else {		sp->wait = &wait;	}	bus = SCSI_BUS_32(cmd);	target = SCSI_TCN_32(cmd);	lun = SCSI_LUN_32(cmd);	/* Overloading result.  Here it means the success or fail of the	 * *issue* of the action.  When we return from the routine, it must	 * mean the actual success or fail of the action */	result = FAILED;	switch (action) {	case FAIL:		break;	case ABORT_COMMAND:		if ((sp->flags & SRB_ABORT_PENDING)) {			printk(KERN_WARNING			       "scsi(): Command has a pending abort "			       "message - ABORT_PENDING.\n");			/* This should technically be impossible since we			 * now wait for abort completion */			break;		}		for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {			if (sp == ha->outstanding_cmds[i]) {				dprintk(1, "qla1280: RISC aborting command\n");				if (qla1280_abort_command(ha, sp, i) == 0)					result = SUCCESS;				else {					/*					 * Since we don't know what might					 * have happend to the command, it					 * is unsafe to remove it from the					 * device's queue at this point.					 * Wait and let the escalation					 * process take care of it.					 */					printk(KERN_WARNING					       "scsi(%li:%i:%i:%i): Unable"					       " to abort command!\n",					       ha->host_no, bus, target, lun);				}			}		}		break;	case ABORT_DEVICE:		ha->flags.in_reset = 1;		if (qla1280_verbose)			printk(KERN_INFO			       "scsi(%ld:%d:%d:%d): Queueing abort device "			       "command.\n", ha->host_no, bus, target, lun);		if (qla1280_abort_device(ha, bus, target, lun) == 0)			result = SUCCESS;		break;	case DEVICE_RESET:		if (qla1280_verbose)			printk(KERN_INFO			       "scsi(%ld:%d:%d:%d): Queueing device reset "			       "command.\n", ha->host_no, bus, target, lun);		ha->flags.in_reset = 1;		if (qla1280_device_reset(ha, bus, target) == 0)			result = SUCCESS;		break;	case BUS_RESET:		if (qla1280_verbose)			printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS "			       "DEVICE RESET\n", ha->host_no, bus);		ha->flags.in_reset = 1;		if (qla1280_bus_reset(ha, bus == 0))			result = SUCCESS;		break;	case ADAPTER_RESET:	default:		if (qla1280_verbose) {			printk(KERN_INFO			       "scsi(%ld): Issued ADAPTER RESET\n",			       ha->host_no);			printk(KERN_INFO "scsi(%ld): I/O processing will "			       "continue automatically\n", ha->host_no);		}		ha->flags.reset_active = 1;		/*		 * We restarted all of the commands automatically, so the		 * mid-level code can expect completions momentitarily.		 */		if (qla1280_abort_isp(ha) == 0)			result = SUCCESS;		ha->flags.reset_active = 0;	}	if (!list_empty(&ha->done_q))		qla1280_done(ha);	ha->flags.in_reset = 0;	/* If we didn't manage to issue the action, or we have no	 * command to wait for, exit here */	if (result == FAILED || handle == NULL ||	    handle == (unsigned char *)INVALID_HANDLE) {		/*		 * Clear completion queue to avoid qla1280_done() trying		 * to complete the command at a later stage after we		 * have exited the current context		 */		sp->wait = NULL;		goto leave;	}	/* set up a timer just in case we're really jammed */	init_timer(&timer);	timer.expires = jiffies + 4*HZ;	timer.data = (unsigned long)cmd;	timer.function = qla1280_error_wait_timeout;	add_timer(&timer);	/* wait for the action to complete (or the timer to expire) */	spin_unlock_irq(HOST_LOCK);	wait_for_completion(&wait);	del_timer_sync(&timer);	spin_lock_irq(HOST_LOCK);	sp->wait = NULL;	/* the only action we might get a fail for is abort */	if (action == ABORT_COMMAND) {		if(sp->flags & SRB_ABORTED)			result = SUCCESS;		else			result = FAILED;	} leave:	dprintk(1, "RESET returning %d\n", result);	LEAVE("qla1280_error_action");	return result;}/************************************************************************** *   qla1280_abort *     Abort the specified SCSI command(s). **************************************************************************/static intqla1280_eh_abort(struct scsi_cmnd * cmd){	return qla1280_error_action(cmd, ABORT_COMMAND);}/************************************************************************** *   qla1280_device_reset *     Reset the specified SCSI device **************************************************************************/static intqla1280_eh_device_reset(struct scsi_cmnd *cmd){	return qla1280_error_action(cmd, DEVICE_RESET);}/************************************************************************** *   qla1280_bus_reset *     Reset the specified bus. **************************************************************************/static intqla1280_eh_bus_reset(struct scsi_cmnd *cmd){	return qla1280_error_action(cmd, BUS_RESET);}/************************************************************************** *   qla1280_adapter_reset *     Reset the specified adapter (both channels) **************************************************************************/static intqla1280_eh_adapter_reset(struct scsi_cmnd *cmd){	return qla1280_error_action(cmd, ADAPTER_RESET);}static intqla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,		  sector_t capacity, int geom[]){	int heads, sectors, cylinders;	heads = 64;	sectors = 32;	cylinders = (unsigned long)capacity / (heads * sectors);	if (cylinders > 1024) {		heads = 255;		sectors = 63;		cylinders = (unsigned long)capacity / (heads * sectors);		/* if (cylinders > 1023)		   cylinders = 1023; */	}	geom[0] = heads;	geom[1] = sectors;	geom[2] = cylinders;	return 0;}#if LINUX_VERSION_CODE < 0x020600static intqla1280_detect(Scsi_Host_Template *template){	struct pci_device_id *id = &qla1280_pci_tbl[0];	struct pci_dev *pdev = NULL;	int num_hosts = 0;	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {		printk(KERN_WARNING		       "qla1280: struct srb too big, aborting\n");		return 0;	}	if ((DMA_BIDIRECTIONAL != PCI_DMA_BIDIRECTIONAL) ||	    (DMA_TO_DEVICE != PCI_DMA_TODEVICE) ||	    (DMA_FROM_DEVICE != PCI_DMA_FROMDEVICE) ||	    (DMA_NONE != PCI_DMA_NONE)) {		printk(KERN_WARNING

⌨️ 快捷键说明

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