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

📄 qla_isr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
				    "frame(s) detected (%x of %x bytes)..."				    "retrying command.\n", ha->host_no,				    cp->device->channel, cp->device->id,				    cp->device->lun, resid,				    cp->request_bufflen));				cp->result = DID_BUS_BUSY << 16;				break;			}			/* Handle mid-layer underflow */			if ((unsigned)(cp->request_bufflen - resid) <			    cp->underflow) {				qla_printk(KERN_INFO, ha,				    "scsi(%ld:%d:%d:%d): Mid-layer underflow "				    "detected (%x of %x bytes)...returning "				    "error status.\n", ha->host_no,				    cp->device->channel, cp->device->id,				    cp->device->lun, resid,				    cp->request_bufflen);				cp->result = DID_ERROR << 16;				break;			}			/* Everybody online, looking good... */			cp->result = DID_OK << 16;		}		break;	case CS_DATA_OVERRUN:		DEBUG2(printk(KERN_INFO		    "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",		    ha->host_no, cp->device->id, cp->device->lun, comp_status,		    scsi_status));		DEBUG2(printk(KERN_INFO		    "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",		    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],		    cp->cmnd[4], cp->cmnd[5]));		DEBUG2(printk(KERN_INFO		    "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "		    "status!\n",		    cp->serial_number, cp->request_bufflen, resid_len));		cp->result = DID_ERROR << 16;		break;	case CS_PORT_LOGGED_OUT:	case CS_PORT_CONFIG_CHG:	case CS_PORT_BUSY:	case CS_INCOMPLETE:	case CS_PORT_UNAVAILABLE:		/*		 * If the port is in Target Down state, return all IOs for this		 * Target with DID_NO_CONNECT ELSE Queue the IOs in the		 * retry_queue.		 */		DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "		    "pid=%ld, compl status=0x%x, port state=0x%x\n",		    ha->host_no, cp->device->id, cp->device->lun,		    cp->serial_number, comp_status,		    atomic_read(&fcport->state)));		cp->result = DID_BUS_BUSY << 16;		if (atomic_read(&fcport->state) == FCS_ONLINE) {			qla2x00_mark_device_lost(ha, fcport, 1);		}		break;	case CS_RESET:		DEBUG2(printk(KERN_INFO		    "scsi(%ld): RESET status detected 0x%x-0x%x.\n",		    ha->host_no, comp_status, scsi_status));		cp->result = DID_RESET << 16;		break;	case CS_ABORTED:		/*		 * hv2.19.12 - DID_ABORT does not retry the request if we		 * aborted this request then abort otherwise it must be a		 * reset.		 */		DEBUG2(printk(KERN_INFO		    "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",		    ha->host_no, comp_status, scsi_status));		cp->result = DID_RESET << 16;		break;	case CS_TIMEOUT:		cp->result = DID_BUS_BUSY << 16;		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {			DEBUG2(printk(KERN_INFO			    "scsi(%ld:%d:%d:%d): TIMEOUT status detected "			    "0x%x-0x%x\n", ha->host_no, cp->device->channel,			    cp->device->id, cp->device->lun, comp_status,			    scsi_status));			break;		}		DEBUG2(printk(KERN_INFO		    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "		    "sflags=%x.\n", ha->host_no, cp->device->channel,		    cp->device->id, cp->device->lun, comp_status, scsi_status,		    le16_to_cpu(sts->status_flags)));		/* Check to see if logout occurred. */		if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))			qla2x00_mark_device_lost(ha, fcport, 1);		break;	case CS_QUEUE_FULL:		DEBUG2(printk(KERN_INFO		    "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",		    ha->host_no, comp_status, scsi_status));		/* SCSI Mid-Layer handles device queue full */		cp->result = DID_OK << 16 | lscsi_status;		break;	default:		DEBUG3(printk("scsi(%ld): Error detected (unknown status) "		    "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));		qla_printk(KERN_INFO, ha,		    "Unknown status detected 0x%x-0x%x.\n",		    comp_status, scsi_status);		cp->result = DID_ERROR << 16;		break;	}	/* Place command on done queue. */	if (ha->status_srb == NULL)		qla2x00_sp_compl(ha, sp);}/** * qla2x00_status_cont_entry() - Process a Status Continuations entry. * @ha: SCSI driver HA context * @pkt: Entry pointer * * Extended sense data. */static voidqla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt){	uint8_t		sense_sz = 0;	srb_t		*sp = ha->status_srb;	struct scsi_cmnd *cp;	if (sp != NULL && sp->request_sense_length != 0) {		cp = sp->cmd;		if (cp == NULL) {			DEBUG2(printk("%s(): Cmd already returned back to OS "			    "sp=%p sp->state:%d\n", __func__, sp, sp->state));			qla_printk(KERN_INFO, ha,			    "cmd is NULL: already returned to OS (sp=%p)\n",			    sp);			ha->status_srb = NULL;			return;		}		if (sp->request_sense_length > sizeof(pkt->data)) {			sense_sz = sizeof(pkt->data);		} else {			sense_sz = sp->request_sense_length;		}		/* Move sense data. */		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))			host_to_fcp_swap(pkt->data, sizeof(pkt->data));		memcpy(sp->request_sense_ptr, pkt->data, sense_sz);		DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));		sp->request_sense_ptr += sense_sz;		sp->request_sense_length -= sense_sz;		/* Place command on done queue. */		if (sp->request_sense_length == 0) {			ha->status_srb = NULL;			qla2x00_sp_compl(ha, sp);		}	}}/** * qla2x00_error_entry() - Process an error entry. * @ha: SCSI driver HA context * @pkt: Entry pointer */static voidqla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt){	srb_t *sp;#if defined(QL_DEBUG_LEVEL_2)	if (pkt->entry_status & RF_INV_E_ORDER)		qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);	else if (pkt->entry_status & RF_INV_E_COUNT)		qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);	else if (pkt->entry_status & RF_INV_E_PARAM)		qla_printk(KERN_ERR, ha,		    "%s: Invalid Entry Parameter\n", __func__);	else if (pkt->entry_status & RF_INV_E_TYPE)		qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);	else if (pkt->entry_status & RF_BUSY)		qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);	else		qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);#endif	/* Validate handle. */	if (pkt->handle < MAX_OUTSTANDING_COMMANDS)		sp = ha->outstanding_cmds[pkt->handle];	else		sp = NULL;	if (sp) {		/* Free outstanding command slot. */		ha->outstanding_cmds[pkt->handle] = NULL;		/* Bad payload or header */		if (pkt->entry_status &		    (RF_INV_E_ORDER | RF_INV_E_COUNT |		     RF_INV_E_PARAM | RF_INV_E_TYPE)) {			sp->cmd->result = DID_ERROR << 16;		} else if (pkt->entry_status & RF_BUSY) {			sp->cmd->result = DID_BUS_BUSY << 16;		} else {			sp->cmd->result = DID_ERROR << 16;		}		qla2x00_sp_compl(ha, sp);	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==	    COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {		DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",		    ha->host_no));		qla_printk(KERN_WARNING, ha,		    "Error entry - invalid handle\n");		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);		if (ha->dpc_wait && !ha->dpc_active)			up(ha->dpc_wait);	}}/** * qla2x00_ms_entry() - Process a Management Server entry. * @ha: SCSI driver HA context * @index: Response queue out pointer */static voidqla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt){	srb_t          *sp;	DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",	    __func__, ha->host_no, pkt, pkt->handle1));	/* Validate handle. */ 	if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) 		sp = ha->outstanding_cmds[pkt->handle1];	else		sp = NULL;	if (sp == NULL) {		DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",		    ha->host_no));		qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);		return;	}	CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);	CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;	/* Free outstanding command slot. */	ha->outstanding_cmds[pkt->handle1] = NULL;	qla2x00_sp_compl(ha, sp);}/** * qla24xx_mbx_completion() - Process mailbox command completions. * @ha: SCSI driver HA context * @mb0: Mailbox0 register */static voidqla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0){	uint16_t	cnt;	uint16_t __iomem *wptr;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	/* Load return mailbox registers. */	ha->flags.mbox_int = 1;	ha->mailbox_out[0] = mb0;	wptr = (uint16_t __iomem *)&reg->mailbox1;	for (cnt = 1; cnt < ha->mbx_count; cnt++) {		ha->mailbox_out[cnt] = RD_REG_WORD(wptr);		wptr++;	}	if (ha->mcp) {		DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",		    __func__, ha->host_no, ha->mcp->mb[0]));	} else {		DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",		    __func__, ha->host_no));	}}/** * qla24xx_process_response_queue() - Process response queue entries. * @ha: SCSI driver HA context */voidqla24xx_process_response_queue(struct scsi_qla_host *ha){	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	struct sts_entry_24xx *pkt;	if (!ha->flags.online)		return;	while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {		pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;		ha->rsp_ring_index++;		if (ha->rsp_ring_index == ha->response_q_length) {			ha->rsp_ring_index = 0;			ha->response_ring_ptr = ha->response_ring;		} else {			ha->response_ring_ptr++;		}		if (pkt->entry_status != 0) {			DEBUG3(printk(KERN_INFO			    "scsi(%ld): Process error entry.\n", ha->host_no));			qla2x00_error_entry(ha, (sts_entry_t *) pkt);			((response_t *)pkt)->signature = RESPONSE_PROCESSED;			wmb();			continue;		}		switch (pkt->entry_type) {		case STATUS_TYPE:			qla2x00_status_entry(ha, pkt);			break;		case STATUS_CONT_TYPE:			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);			break;		case MS_IOCB_TYPE:			qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);			break;		default:			/* Type Not Supported. */			DEBUG4(printk(KERN_WARNING			    "scsi(%ld): Received unknown response pkt type %x "			    "entry status=%x.\n",			    ha->host_no, pkt->entry_type, pkt->entry_status));			break;		}		((response_t *)pkt)->signature = RESPONSE_PROCESSED;		wmb();	}	/* Adjust ring index */	WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);}/** * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. * @irq: * @dev_id: SCSI driver HA context * @regs: * * Called by system whenever the host adapter generates an interrupt. * * Returns handled flag. */irqreturn_tqla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs){	scsi_qla_host_t	*ha;	struct device_reg_24xx __iomem *reg;	int		status;	unsigned long	flags;	unsigned long	iter;	uint32_t	stat;	uint32_t	hccr;	uint16_t	mb[4];	ha = (scsi_qla_host_t *) dev_id;	if (!ha) {		printk(KERN_INFO		    "%s(): NULL host pointer\n", __func__);		return IRQ_NONE;	}	reg = &ha->iobase->isp24;	status = 0;	spin_lock_irqsave(&ha->hardware_lock, flags);	for (iter = 50; iter--; ) {		stat = RD_REG_DWORD(&reg->host_status);		if (stat & HSRX_RISC_PAUSED) {			hccr = RD_REG_DWORD(&reg->hccr);			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "			    "Dumping firmware!\n", hccr);			qla24xx_fw_dump(ha, 1);			set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);			break;		} else if ((stat & HSRX_RISC_INT) == 0)			break;		switch (stat & 0xff) {		case 0x1:		case 0x2:		case 0x10:		case 0x11:			qla24xx_mbx_completion(ha, MSW(stat));			status |= MBX_INTERRUPT;			break;		case 0x12:			mb[0] = MSW(stat);			mb[1] = RD_REG_WORD(&reg->mailbox1);			mb[2] = RD_REG_WORD(&reg->mailbox2);			mb[3] = RD_REG_WORD(&reg->mailbox3);			qla2x00_async_event(ha, mb);			break;		case 0x13:			qla24xx_process_response_queue(ha);			break;		default:			DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "			    "(%d).\n",			    ha->host_no, stat & 0xff));			break;		}		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);		RD_REG_DWORD_RELAXED(&reg->hccr);	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {		spin_lock_irqsave(&ha->mbx_reg_lock, flags);		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);		up(&ha->mbx_intr_sem);		spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);	}	return IRQ_HANDLED;}/** * qla24xx_ms_entry() - Process a Management Server entry. * @ha: SCSI driver HA context * @index: Response queue out pointer */static voidqla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt){	srb_t          *sp;	DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",	    __func__, ha->host_no, pkt, pkt->handle));	DEBUG9(printk("%s: ct pkt dump:\n", __func__);)	DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)	/* Validate handle. */ 	if (pkt->handle < MAX_OUTSTANDING_COMMANDS) 		sp = ha->outstanding_cmds[pkt->handle];	else		sp = NULL;	if (sp == NULL) {		DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",		    ha->host_no));		DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",		    ha->host_no));		qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",		    pkt->handle);		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);		return;	}	CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);	CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;	/* Free outstanding command slot. */	ha->outstanding_cmds[pkt->handle] = NULL;	qla2x00_sp_compl(ha, sp);}

⌨️ 快捷键说明

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