diff options
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
| -rw-r--r-- | drivers/message/fusion/mptscsih.c | 143 | 
1 files changed, 32 insertions, 111 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 59b8f53d1ec..2a1c6f21af2 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -792,6 +792,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)  			 * than an unsolicited DID_ABORT.  			 */  			sc->result = DID_RESET << 16; +			break;  		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */  			if (ioc->bus_type == FC) @@ -827,10 +828,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)  				 * DID_SOFT_ERROR is set.  				 */  				if (ioc->bus_type == SPI) { -					if (pScsiReq->CDB[0] == READ_6  || +					if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||  					    pScsiReq->CDB[0] == READ_10 ||  					    pScsiReq->CDB[0] == READ_12 || -					    pScsiReq->CDB[0] == READ_16 || +						(pScsiReq->CDB[0] == READ_16 && +						((pScsiReq->CDB[1] & 0x02) == 0)) ||  					    pScsiReq->CDB[0] == VERIFY  ||  					    pScsiReq->CDB[0] == VERIFY_16) {  						if (scsi_bufflen(sc) != @@ -1024,7 +1026,7 @@ out:   *   *	Must be called while new I/Os are being queued.   */ -static void +void  mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)  {  	MPT_ADAPTER *ioc = hd->ioc; @@ -1055,6 +1057,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)  		sc->scsi_done(sc);  	}  } +EXPORT_SYMBOL(mptscsih_flush_running_cmds);  /*   *	mptscsih_search_running_cmds - Delete any commands associated @@ -1281,101 +1284,17 @@ mptscsih_info(struct Scsi_Host *SChost)  	return h->info_kbuf;  } -struct info_str { -	char *buffer; -	int   length; -	int   offset; -	int   pos; -}; - -static void -mptscsih_copy_mem_info(struct info_str *info, char *data, int len) -{ -	if (info->pos + len > info->length) -		len = info->length - info->pos; - -	if (info->pos + len < info->offset) { -		info->pos += len; -		return; -	} - -	if (info->pos < info->offset) { -	        data += (info->offset - info->pos); -	        len  -= (info->offset - info->pos); -	} - -	if (len > 0) { -                memcpy(info->buffer + info->pos, data, len); -                info->pos += len; -	} -} - -static int -mptscsih_copy_info(struct info_str *info, char *fmt, ...) -{ -	va_list args; -	char buf[81]; -	int len; - -	va_start(args, fmt); -	len = vsprintf(buf, fmt, args); -	va_end(args); - -	mptscsih_copy_mem_info(info, buf, len); -	return len; -} - -static int -mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len) -{ -	struct info_str info; - -	info.buffer	= pbuf; -	info.length	= len; -	info.offset	= offset; -	info.pos	= 0; - -	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name); -	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word); -	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts); -	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth); - -	return ((info.pos > info.offset) ? info.pos - info.offset : 0); -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - *	mptscsih_proc_info - Return information about MPT adapter - * 	@host:   scsi host struct - * 	@buffer: if write, user data; if read, buffer for user - *	@start: returns the buffer address - * 	@offset: if write, 0; if read, the current offset into the buffer from - * 		 the previous read. - * 	@length: if write, return length; - *	@func:   write = 1; read = 0 - * - *	(linux scsi_host_template.info routine) - */ -int -mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, -			int length, int func) +int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)  {  	MPT_SCSI_HOST	*hd = shost_priv(host);  	MPT_ADAPTER	*ioc = hd->ioc; -	int size = 0; -	if (func) { -		/* -		 * write is not supported -		 */ -	} else { -		if (start) -			*start = buffer; +	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name); +	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word); +	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts); +	seq_printf(m, "MaxQ=%d\n", ioc->req_depth); -		size = mptscsih_host_info(ioc, buffer, offset, length); -	} - -	return size; +	return 0;  }  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1385,7 +1304,6 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off  /**   *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.   *	@SCpnt: Pointer to scsi_cmnd structure - *	@done: Pointer SCSI mid-layer IO completion function   *   *	(linux scsi_host_template.queuecommand routine)   *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest @@ -1394,7 +1312,7 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off   *	Returns 0. (rtn value discarded by linux scsi mid-layer)   */  int -mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +mptscsih_qcmd(struct scsi_cmnd *SCpnt)  {  	MPT_SCSI_HOST		*hd;  	MPT_FRAME_HDR		*mf; @@ -1410,16 +1328,12 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))  	hd = shost_priv(SCpnt->device->host);  	ioc = hd->ioc; -	SCpnt->scsi_done = done; -	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n", -		ioc->name, SCpnt, done)); +	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n", +		ioc->name, SCpnt)); -	if (ioc->taskmgmt_quiesce_io) { -		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n", -			ioc->name, SCpnt)); +	if (ioc->taskmgmt_quiesce_io)  		return SCSI_MLQUEUE_HOST_BUSY; -	}  	/*  	 *  Put together a MPT SCSI request... @@ -1632,7 +1546,13 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,  		return 0;  	} -	if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { +	/* DOORBELL ACTIVE check is not required if +	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported. +	*/ + +	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) +		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) && +		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {  		printk(MYIOC_s_WARN_FMT  			"TaskMgmt type=%x: ioc_state: "  			"DOORBELL_ACTIVE (0x%x)!\n", @@ -1731,7 +1651,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,  		printk(MYIOC_s_WARN_FMT  		       "Issuing Reset from %s!! doorbell=0x%08x\n",  		       ioc->name, __func__, mpt_GetIocState(ioc, 0)); -		retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); +		retval = (ioc->bus_type == SAS) ? +			mpt_HardResetHandler(ioc, CAN_SLEEP) : +			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);  		mpt_free_msg_frame(ioc, mf);  	} @@ -1773,7 +1695,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)  	int		 scpnt_idx;  	int		 retval;  	VirtDevice	 *vdevice; -	ulong	 	 sn = SCpnt->serial_number;  	MPT_ADAPTER	*ioc;  	/* If we can't locate our host adapter structure, return FAILED status. @@ -1859,8 +1780,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)  			 vdevice->vtarget->id, vdevice->lun,  			 ctx2abort, mptscsih_get_tm_timeout(ioc)); -	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx && -	    SCpnt->serial_number == sn) { +	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {  		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT  		    "task abort: command still in active list! (sc=%p)\n",  		    ioc->name, SCpnt)); @@ -1873,8 +1793,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)  	}   out: -	printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", -	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt); +	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n", +	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval, +	    SCpnt);  	return retval;  } @@ -1911,7 +1832,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)  	vdevice = SCpnt->device->hostdata;  	if (!vdevice || !vdevice->vtarget) { -		retval = SUCCESS; +		retval = 0;  		goto out;  	} @@ -3341,7 +3262,7 @@ EXPORT_SYMBOL(mptscsih_shutdown);  EXPORT_SYMBOL(mptscsih_suspend);  EXPORT_SYMBOL(mptscsih_resume);  #endif -EXPORT_SYMBOL(mptscsih_proc_info); +EXPORT_SYMBOL(mptscsih_show_info);  EXPORT_SYMBOL(mptscsih_info);  EXPORT_SYMBOL(mptscsih_qcmd);  EXPORT_SYMBOL(mptscsih_slave_destroy);  | 
