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

📄 qla1280.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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:		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);		if (qla1280_device_reset(ha, bus, target) == 0)			result = SUCCESS;		break;	case BUS_RESET:		if (qla1280_verbose)			printk(KERN_INFO "qla1280(%ld:%d): Issued bus "			       "reset.\n", ha->host_no, bus);		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);	/* 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(ha->host->host_lock);	wait_for_completion(&wait);	del_timer_sync(&timer);	spin_lock_irq(ha->host->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){	int rc;	spin_lock_irq(cmd->device->host->host_lock);	rc = qla1280_error_action(cmd, ABORT_COMMAND);	spin_unlock_irq(cmd->device->host->host_lock);	return rc;}/************************************************************************** *   qla1280_device_reset *     Reset the specified SCSI device **************************************************************************/static intqla1280_eh_device_reset(struct scsi_cmnd *cmd){	int rc;	spin_lock_irq(cmd->device->host->host_lock);	rc = qla1280_error_action(cmd, DEVICE_RESET);	spin_unlock_irq(cmd->device->host->host_lock);	return rc;}/************************************************************************** *   qla1280_bus_reset *     Reset the specified bus. **************************************************************************/static intqla1280_eh_bus_reset(struct scsi_cmnd *cmd){	int rc;	spin_lock_irq(cmd->device->host->host_lock);	rc = qla1280_error_action(cmd, BUS_RESET);	spin_unlock_irq(cmd->device->host->host_lock);	return rc;}/************************************************************************** *   qla1280_adapter_reset *     Reset the specified adapter (both channels) **************************************************************************/static intqla1280_eh_adapter_reset(struct scsi_cmnd *cmd){	int rc;	spin_lock_irq(cmd->device->host->host_lock);	rc = qla1280_error_action(cmd, ADAPTER_RESET);	spin_unlock_irq(cmd->device->host->host_lock);	return rc;}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;} /* disable risc and host interrupts */static inline voidqla1280_disable_intrs(struct scsi_qla_host *ha){	WRT_REG_WORD(&ha->iobase->ictrl, 0);	RD_REG_WORD(&ha->iobase->ictrl);	/* PCI Posted Write flush */}/* enable risc and host interrupts */static inline voidqla1280_enable_intrs(struct scsi_qla_host *ha){	WRT_REG_WORD(&ha->iobase->ictrl, (ISP_EN_INT | ISP_EN_RISC));	RD_REG_WORD(&ha->iobase->ictrl);	/* PCI Posted Write flush */}/************************************************************************** * qla1280_intr_handler *   Handles the H/W interrupt **************************************************************************/static irqreturn_tqla1280_intr_handler(int irq, void *dev_id){	struct scsi_qla_host *ha;	struct device_reg __iomem *reg;	u16 data;	int handled = 0;	ENTER_INTR ("qla1280_intr_handler");	ha = (struct scsi_qla_host *)dev_id;	spin_lock(ha->host->host_lock);	ha->isr_count++;	reg = ha->iobase;	qla1280_disable_intrs(ha);	data = qla1280_debounce_register(&reg->istatus);	/* Check for pending interrupts. */	if (data & RISC_INT) {			qla1280_isr(ha, &ha->done_q);		handled = 1;	}	if (!list_empty(&ha->done_q))		qla1280_done(ha);	spin_unlock(ha->host->host_lock);	qla1280_enable_intrs(ha);	LEAVE_INTR("qla1280_intr_handler");	return IRQ_RETVAL(handled);}static intqla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target){	uint8_t mr;	uint16_t mb[MAILBOX_REGISTER_COUNT];	struct nvram *nv;	int status, lun;	nv = &ha->nvram;	mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;	/* Set Target Parameters. */	mb[0] = MBC_SET_TARGET_PARAMETERS;	mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8);	mb[2] = nv->bus[bus].target[target].parameter.renegotiate_on_error << 8;	mb[2] |= nv->bus[bus].target[target].parameter.stop_queue_on_check << 9;	mb[2] |= nv->bus[bus].target[target].parameter.auto_request_sense << 10;	mb[2] |= nv->bus[bus].target[target].parameter.tag_queuing << 11;	mb[2] |= nv->bus[bus].target[target].parameter.enable_sync << 12;	mb[2] |= nv->bus[bus].target[target].parameter.enable_wide << 13;	mb[2] |= nv->bus[bus].target[target].parameter.parity_checking << 14;	mb[2] |= nv->bus[bus].target[target].parameter.disconnect_allowed << 15;	if (IS_ISP1x160(ha)) {		mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;		mb[3] =	(nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8);		mb[6] =	(nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8) |			 nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;		mr |= BIT_6;	} else {		mb[3] =	(nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8);	}	mb[3] |= nv->bus[bus].target[target].sync_period;	status = qla1280_mailbox_command(ha, mr, mb);	/* Set Device Queue Parameters. */	for (lun = 0; lun < MAX_LUNS; lun++) {		mb[0] = MBC_SET_DEVICE_QUEUE;		mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8);		mb[1] |= lun;		mb[2] = nv->bus[bus].max_queue_depth;		mb[3] = nv->bus[bus].target[target].execution_throttle;		status |= qla1280_mailbox_command(ha, 0x0f, mb);	}	if (status)		printk(KERN_WARNING "scsi(%ld:%i:%i): "		       "qla1280_set_target_parameters() failed\n",		       ha->host_no, bus, target);	return status;}/************************************************************************** *   qla1280_slave_configure * * Description: *   Determines the queue depth for a given device.  There are two ways *   a queue depth can be obtained for a tagged queueing device.  One *   way is the default queue depth which is determined by whether *   If it is defined, then it is used *   as the default queue depth.  Otherwise, we use either 4 or 8 as the *   default queue depth (dependent on the number of hardware SCBs). **************************************************************************/static intqla1280_slave_configure(struct scsi_device *device){	struct scsi_qla_host *ha;	int default_depth = 3;	int bus = device->channel;	int target = device->id;	int status = 0;	struct nvram *nv;	unsigned long flags;	ha = (struct scsi_qla_host *)device->host->hostdata;	nv = &ha->nvram;

⌨️ 快捷键说明

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