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

📄 qla_isr.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		 */		memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));		if (!(scsi_status & SS_SENSE_LEN_VALID))			break;		if (le16_to_cpu(pkt->req_sense_length) <		    sizeof(cp->sense_buffer))			sense_sz = le16_to_cpu(pkt->req_sense_length);		else			sense_sz = sizeof(cp->sense_buffer);		CMD_ACTUAL_SNSLEN(cp) = sense_sz;		sp->request_sense_length = sense_sz;		sp->request_sense_ptr = cp->sense_buffer;		if (sp->request_sense_length > 32)			sense_sz = 32;		memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);		sp->request_sense_ptr += sense_sz;		sp->request_sense_length -= sense_sz;		if (sp->request_sense_length != 0)			ha->status_srb = sp;		if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&		    qla2x00_check_sense(cp, lq) == QLA_SUCCESS) {			/* Throw away status_cont if any */			ha->status_srb = NULL;			add_to_scsi_retry_queue(ha, sp);			return;		}		DEBUG5(printk("%s(): Check condition Sense data, "		    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",		    __func__, ha->host_no, b, t, l, cp,		    cp->serial_number));		if (sense_sz)			DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,			    CMD_ACTUAL_SNSLEN(cp)));		break;	case CS_DATA_UNDERRUN:		DEBUG2(printk(KERN_INFO		    "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",		    ha->host_no, t, l, comp_status, scsi_status));		resid = le32_to_cpu(pkt->residual_length);		if (scsi_status & SS_RESIDUAL_UNDER) {			cp->resid = resid;			CMD_RESID_LEN(cp) = resid;		}		/*		 * Check to see if SCSI Status is non zero. If so report SCSI 		 * Status.		 */		if (lscsi_status != 0) {			if (lscsi_status == SS_BUSY_CONDITION) {				cp->result = DID_BUS_BUSY << 16 |				    lscsi_status;				break;			}			cp->result = DID_OK << 16 | lscsi_status;			if (lscsi_status != SS_CHECK_CONDITION)				break;			/* Copy Sense Data into sense buffer */			memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));			if (!(scsi_status & SS_SENSE_LEN_VALID))				break;			if (le16_to_cpu(pkt->req_sense_length) <			    sizeof(cp->sense_buffer))				sense_sz = le16_to_cpu(pkt->req_sense_length);			else				sense_sz = sizeof(cp->sense_buffer);			CMD_ACTUAL_SNSLEN(cp) = sense_sz;			sp->request_sense_length = sense_sz;			sp->request_sense_ptr = cp->sense_buffer;			if (sp->request_sense_length > 32) 				sense_sz = 32;			memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);			sp->request_sense_ptr += sense_sz;			sp->request_sense_length -= sense_sz;			if (sp->request_sense_length != 0)				ha->status_srb = sp;			if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&			    (qla2x00_check_sense(cp, lq) == QLA_SUCCESS)) {				ha->status_srb = NULL;				add_to_scsi_retry_queue(ha, sp);				return;			}			DEBUG5(printk("%s(): Check condition Sense data, "			    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",			    __func__, ha->host_no, b, t, l, cp,			    cp->serial_number));			if (sense_sz)				DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,				    CMD_ACTUAL_SNSLEN(cp)));		} else {			/*			 * If RISC reports underrun and target does not report			 * it then we must have a lost frame, so tell upper			 * layer to retry it by reporting a bus busy.			 */			if (!(scsi_status & SS_RESIDUAL_UNDER)) {				DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "				    "frame(s) detected (%x of %x bytes)..."				    "retrying command.\n",				    ha->host_no, b, t, l, resid,				    cp->request_bufflen));				cp->result = DID_BUS_BUSY << 16;				ha->dropped_frame_error_cnt++;				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, b, t, l, 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, t, l, 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,		    le32_to_cpu(pkt->residual_length)));		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.		 */		fcport = sp->fclun->fcport;		DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "		    "pid=%ld, compl status=0x%x, port state=0x%x\n",		    ha->host_no, t, l, cp->serial_number, comp_status,		    atomic_read(&fcport->state)));		if ((sp->flags & (SRB_IOCTL | SRB_TAPE)) ||		    atomic_read(&fcport->state) == FCS_DEVICE_DEAD) {			cp->result = DID_NO_CONNECT << 16;			if (atomic_read(&ha->loop_state) == LOOP_DOWN) 				sp->err_id = SRB_ERR_LOOP;			else				sp->err_id = SRB_ERR_PORT;			add_to_done_queue(ha, sp);		} else {			qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);			add_to_retry_queue(ha, sp);		}		if (atomic_read(&fcport->state) == FCS_ONLINE) {			qla2x00_mark_device_lost(ha, fcport, 1);		}		return;		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));		if (sp->flags & (SRB_IOCTL | SRB_TAPE)) {			cp->result = DID_RESET << 16;		} else {			qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);			add_to_retry_queue(ha, sp);			return;		}		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:		DEBUG2(printk(KERN_INFO		    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "		    "sflags=%x.\n", ha->host_no, b, t, l, comp_status,		    scsi_status, le16_to_cpu(pkt->status_flags)));		cp->result = DID_BUS_BUSY << 16;		fcport = lq->fclun->fcport;		/* Check to see if logout occurred */		if ((le16_to_cpu(pkt->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; 		/* TODO: ??? */		/* Adjust queue depth */		ret = scsi_track_queue_full(cp->device,		    sp->lun_queue->out_cnt - 1);		if (ret) {			qla_printk(KERN_INFO, ha,			    "scsi(%ld:%d:%d:%d): Queue depth adjusted to %d.\n",			    ha->host_no, cp->device->channel, cp->device->id,			    cp->device->lun, ret);		}		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)		add_to_done_queue(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. */		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) {			add_to_done_queue(ha, sp);			ha->status_srb = NULL;		}	}}/** * 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;		if (ha->actthreads)			ha->actthreads--;		sp->lun_queue->out_cnt--;		/* 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;		}		/* Place command on done queue. */		add_to_done_queue(ha, sp);	} else if (pkt->entry_type == COMMAND_A64_TYPE ||	    pkt->entry_type == COMMAND_TYPE) {		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;	add_to_done_queue(ha, sp);}/** * qla2x00_check_sense() - Perform any sense data interrogation. * @cp: SCSI Command * @lq: Lun queue * * Returns QLA_SUCCESS if the lun queue is suspended, else * QLA_FUNCTION_FAILED  (lun queue not suspended). */static int qla2x00_check_sense(struct scsi_cmnd *cp, os_lun_t *lq){	scsi_qla_host_t	*ha;	srb_t		*sp;	fc_port_t	*fcport;	ha = (scsi_qla_host_t *) cp->device->host->hostdata;	if ((cp->sense_buffer[0] & 0x70) != 0x70) {		return (QLA_FUNCTION_FAILED);	}	sp = (srb_t * )CMD_SP(cp);	sp->flags |= SRB_GOT_SENSE;	switch (cp->sense_buffer[2] & 0xf) {	case RECOVERED_ERROR:		cp->result = DID_OK << 16;		cp->sense_buffer[0] = 0;		break;	case NOT_READY:		fcport = lq->fclun->fcport;		/*		 * Suspend the lun only for hard disk device type.		 */		if ((fcport->flags & FCF_TAPE_PRESENT) == 0 &&		    lq->q_state != LUN_STATE_TIMEOUT) {			/*			 * If target is in process of being ready then suspend			 * lun for 6 secs and retry all the commands.			 */			if (cp->sense_buffer[12] == 0x4 &&			    cp->sense_buffer[13] == 0x1) {				/* Suspend the lun for 6 secs */				qla2x00_suspend_lun(ha, lq, 6,				    ql2xsuspendcount);				return (QLA_SUCCESS);			}		}		break;	}	return (QLA_FUNCTION_FAILED);}

⌨️ 快捷键说明

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