aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoore, Eric Dean <Eric.Moore@lsil.com>2005-09-14 20:09:10 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-19 13:45:38 -0400
commit466544d8898fc87ed6e2e62ac14af7c50ab7a1a4 (patch)
treea23688bc1424a2af986482bac159768d625b5deb
parent0c33b27deb93178f10778b3d2669af1674793cef (diff)
[SCSI] fusion SAS support (mptsas driver) updates
Summary of Changes: * splitting mpt_interrupt per Christophs suggestion about a month ago * rename ScsiCfgData to SpiCfgData structure, then move all the raid related info into new structure called RaidCfgData. This is done because SAS supports RAID, as well as SPI, so the raid stuff should be seperate. * incorrect timeout calculation for cntdn inside WaitForDoorbellAck and WaitForDoortbellInt * add support for interpreting SAS Log Info * Increase Event Log Size from 0xA to 0x32 * Fix bug in mptsas/mptfc/mptspi - when controller has Initiator Mode Disabled, and only running in TargetMode, the mptctl would panic when loading. The fix is to return 0, instead of -ENODEV, in SCSI LLD respective probe routines * Fix bug in mptlan.c - driver will panic if there is host reset, due to dev being set to zero in mpt_lan_ioc_reset * Fix's for SPI - Echo Buffer * Several fix's in mptscsih_io_done - FCP Response info, RESIDUAL_MISMATCH, Data Underrun, etc. * Cleanup Error Handling - EH handlers, mptscsih_flush_cmds, and zeroing out ScsiLookup from mptscsih_qcmd * Cleanup asyn event handling from mptscsih -> mptscsih_event_process. Also added support for SAS Persistent Table Full, an asyn event Signed-off-by: Eric Moore <Eric.Moore@lsil.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/message/fusion/mptbase.c449
-rw-r--r--drivers/message/fusion/mptbase.h28
-rw-r--r--drivers/message/fusion/mptctl.c4
-rw-r--r--drivers/message/fusion/mptfc.c2
-rw-r--r--drivers/message/fusion/mptlan.c7
-rw-r--r--drivers/message/fusion/mptsas.c2
-rw-r--r--drivers/message/fusion/mptscsih.c447
-rw-r--r--drivers/message/fusion/mptscsih.h8
-rw-r--r--drivers/message/fusion/mptspi.c2
9 files changed, 549 insertions, 400 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 14d62d96ca41..790a2932ded9 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -135,7 +135,6 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
135 135
136static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); 136static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
137static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); 137static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
138//static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
139static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); 138static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
140static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 139static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); 140static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
@@ -178,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
178static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 177static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
179static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 178static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
180static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); 179static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
180static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
181 181
182/* module entry point */ 182/* module entry point */
183static int __init fusion_init (void); 183static int __init fusion_init (void);
@@ -209,6 +209,144 @@ pci_enable_io_access(struct pci_dev *pdev)
209 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 209 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
210} 210}
211 211
212/*
213 * Process turbo (context) reply...
214 */
215static void
216mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
217{
218 MPT_FRAME_HDR *mf = NULL;
219 MPT_FRAME_HDR *mr = NULL;
220 int req_idx = 0;
221 int cb_idx;
222
223 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
224 ioc->name, pa));
225
226 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
227 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
228 req_idx = pa & 0x0000FFFF;
229 cb_idx = (pa & 0x00FF0000) >> 16;
230 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
231 break;
232 case MPI_CONTEXT_REPLY_TYPE_LAN:
233 cb_idx = mpt_lan_index;
234 /*
235 * Blind set of mf to NULL here was fatal
236 * after lan_reply says "freeme"
237 * Fix sort of combined with an optimization here;
238 * added explicit check for case where lan_reply
239 * was just returning 1 and doing nothing else.
240 * For this case skip the callback, but set up
241 * proper mf value first here:-)
242 */
243 if ((pa & 0x58000000) == 0x58000000) {
244 req_idx = pa & 0x0000FFFF;
245 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
246 mpt_free_msg_frame(ioc, mf);
247 mb();
248 return;
249 break;
250 }
251 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
252 break;
253 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
254 cb_idx = mpt_stm_index;
255 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
256 break;
257 default:
258 cb_idx = 0;
259 BUG();
260 }
261
262 /* Check for (valid) IO callback! */
263 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
264 MptCallbacks[cb_idx] == NULL) {
265 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
266 __FUNCTION__, ioc->name, cb_idx);
267 goto out;
268 }
269
270 if (MptCallbacks[cb_idx](ioc, mf, mr))
271 mpt_free_msg_frame(ioc, mf);
272 out:
273 mb();
274}
275
276static void
277mpt_reply(MPT_ADAPTER *ioc, u32 pa)
278{
279 MPT_FRAME_HDR *mf;
280 MPT_FRAME_HDR *mr;
281 int req_idx;
282 int cb_idx;
283 int freeme;
284
285 u32 reply_dma_low;
286 u16 ioc_stat;
287
288 /* non-TURBO reply! Hmmm, something may be up...
289 * Newest turbo reply mechanism; get address
290 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
291 */
292
293 /* Map DMA address of reply header to cpu address.
294 * pa is 32 bits - but the dma address may be 32 or 64 bits
295 * get offset based only only the low addresses
296 */
297
298 reply_dma_low = (pa <<= 1);
299 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
300 (reply_dma_low - ioc->reply_frames_low_dma));
301
302 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
303 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
304 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
305
306 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
307 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
308 DBG_DUMP_REPLY_FRAME(mr)
309
310 /* Check/log IOC log info
311 */
312 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
313 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
314 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
315 if (ioc->bus_type == FC)
316 mpt_fc_log_info(ioc, log_info);
317 else if (ioc->bus_type == SCSI)
318 mpt_sp_log_info(ioc, log_info);
319 else if (ioc->bus_type == SAS)
320 mpt_sas_log_info(ioc, log_info);
321 }
322 if (ioc_stat & MPI_IOCSTATUS_MASK) {
323 if (ioc->bus_type == SCSI &&
324 cb_idx != mpt_stm_index &&
325 cb_idx != mpt_lan_index)
326 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
327 }
328
329
330 /* Check for (valid) IO callback! */
331 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
332 MptCallbacks[cb_idx] == NULL) {
333 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
334 __FUNCTION__, ioc->name, cb_idx);
335 freeme = 0;
336 goto out;
337 }
338
339 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
340
341 out:
342 /* Flush (non-TURBO) reply with a WRITE! */
343 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
344
345 if (freeme)
346 mpt_free_msg_frame(ioc, mf);
347 mb();
348}
349
212/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 350/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
213/* 351/*
214 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler. 352 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -230,164 +368,21 @@ pci_enable_io_access(struct pci_dev *pdev)
230static irqreturn_t 368static irqreturn_t
231mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) 369mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
232{ 370{
233 MPT_ADAPTER *ioc; 371 MPT_ADAPTER *ioc = bus_id;
234 MPT_FRAME_HDR *mf; 372 u32 pa;
235 MPT_FRAME_HDR *mr;
236 u32 pa;
237 int req_idx;
238 int cb_idx;
239 int type;
240 int freeme;
241
242 ioc = (MPT_ADAPTER *)bus_id;
243 373
244 /* 374 /*
245 * Drain the reply FIFO! 375 * Drain the reply FIFO!
246 *
247 * NOTES: I've seen up to 10 replies processed in this loop, so far...
248 * Update: I've seen up to 9182 replies processed in this loop! ??
249 * Update: Limit ourselves to processing max of N replies
250 * (bottom of loop).
251 */ 376 */
252 while (1) { 377 while (1) {
253 378 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
254 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF) 379 if (pa == 0xFFFFFFFF)
255 return IRQ_HANDLED; 380 return IRQ_HANDLED;
256 381 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
257 cb_idx = 0; 382 mpt_reply(ioc, pa);
258 freeme = 0; 383 else
259 384 mpt_turbo_reply(ioc, pa);
260 /* 385 }
261 * Check for non-TURBO reply!
262 */
263 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
264 u32 reply_dma_low;
265 u16 ioc_stat;
266
267 /* non-TURBO reply! Hmmm, something may be up...
268 * Newest turbo reply mechanism; get address
269 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
270 */
271
272 /* Map DMA address of reply header to cpu address.
273 * pa is 32 bits - but the dma address may be 32 or 64 bits
274 * get offset based only only the low addresses
275 */
276 reply_dma_low = (pa = (pa << 1));
277 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
278 (reply_dma_low - ioc->reply_frames_low_dma));
279
280 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
281 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
282 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
283
284 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
285 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
286 DBG_DUMP_REPLY_FRAME(mr)
287
288 /* Check/log IOC log info
289 */
290 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
291 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
292 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
293 if (ioc->bus_type == FC)
294 mpt_fc_log_info(ioc, log_info);
295 else if (ioc->bus_type == SCSI)
296 mpt_sp_log_info(ioc, log_info);
297 }
298 if (ioc_stat & MPI_IOCSTATUS_MASK) {
299 if (ioc->bus_type == SCSI)
300 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
301 }
302 } else {
303 /*
304 * Process turbo (context) reply...
305 */
306 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
307 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
308 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
309 cb_idx = mpt_stm_index;
310 mf = NULL;
311 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
312 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
313 cb_idx = mpt_lan_index;
314 /* Blind set of mf to NULL here was fatal
315 * after lan_reply says "freeme"
316 * Fix sort of combined with an optimization here;
317 * added explicit check for case where lan_reply
318 * was just returning 1 and doing nothing else.
319 * For this case skip the callback, but set up
320 * proper mf value first here:-)
321 */
322 if ((pa & 0x58000000) == 0x58000000) {
323 req_idx = pa & 0x0000FFFF;
324 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
325 freeme = 1;
326 /*
327 * IMPORTANT! Invalidate the callback!
328 */
329 cb_idx = 0;
330 } else {
331 mf = NULL;
332 }
333 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
334 } else {
335 req_idx = pa & 0x0000FFFF;
336 cb_idx = (pa & 0x00FF0000) >> 16;
337 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
338 mr = NULL;
339 }
340 pa = 0; /* No reply flush! */
341 }
342
343#ifdef MPT_DEBUG_IRQ
344 if (ioc->bus_type == SCSI) {
345 /* Verify mf, mr are reasonable.
346 */
347 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
348 || (mf < ioc->req_frames)) ) {
349 printk(MYIOC_s_WARN_FMT
350 "mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
351 cb_idx = 0;
352 pa = 0;
353 freeme = 0;
354 }
355 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
356 || (mr < ioc->reply_frames)) ) {
357 printk(MYIOC_s_WARN_FMT
358 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
359 cb_idx = 0;
360 pa = 0;
361 freeme = 0;
362 }
363 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
364 printk(MYIOC_s_WARN_FMT
365 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
366 cb_idx = 0;
367 pa = 0;
368 freeme = 0;
369 }
370 }
371#endif
372
373 /* Check for (valid) IO callback! */
374 if (cb_idx) {
375 /* Do the callback! */
376 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
377 }
378
379 if (pa) {
380 /* Flush (non-TURBO) reply with a WRITE! */
381 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
382 }
383
384 if (freeme) {
385 /* Put Request back on FreeQ! */
386 mpt_free_msg_frame(ioc, mf);
387 }
388
389 mb();
390 } /* drain reply FIFO */
391 386
392 return IRQ_HANDLED; 387 return IRQ_HANDLED;
393} 388}
@@ -1065,7 +1060,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1065 ioc->name, 1060 ioc->name,
1066 ioc->HostPageBuffer, 1061 ioc->HostPageBuffer,
1067 ioc->HostPageBuffer_dma, 1062 ioc->HostPageBuffer_dma,
1068 hst_page_buffer_sz)); 1063 host_page_buffer_sz));
1069 ioc->alloc_total += host_page_buffer_sz; 1064 ioc->alloc_total += host_page_buffer_sz;
1070 ioc->HostPageBuffer_sz = host_page_buffer_sz; 1065 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1071 break; 1066 break;
@@ -1208,7 +1203,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1208 1203
1209 /* Initilize SCSI Config Data structure 1204 /* Initilize SCSI Config Data structure
1210 */ 1205 */
1211 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData)); 1206 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1212 1207
1213 /* Initialize the running configQ head. 1208 /* Initialize the running configQ head.
1214 */ 1209 */
@@ -1755,8 +1750,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1755 */ 1750 */
1756 if (ret == 0) { 1751 if (ret == 0) {
1757 rc = mpt_do_upload(ioc, sleepFlag); 1752 rc = mpt_do_upload(ioc, sleepFlag);
1758 if (rc != 0) 1753 if (rc == 0) {
1754 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1755 /*
1756 * Maintain only one pointer to FW memory
1757 * so there will not be two attempt to
1758 * downloadboot onboard dual function
1759 * chips (mpt_adapter_disable,
1760 * mpt_diag_reset)
1761 */
1762 ioc->cached_fw = NULL;
1763 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1764 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1765 }
1766 } else {
1759 printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); 1767 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1768 ret = -5;
1769 }
1760 } 1770 }
1761 } 1771 }
1762 } 1772 }
@@ -1997,9 +2007,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
1997 } 2007 }
1998 2008
1999 kfree(ioc->spi_data.nvram); 2009 kfree(ioc->spi_data.nvram);
2000 kfree(ioc->spi_data.pIocPg3); 2010 kfree(ioc->raid_data.pIocPg3);
2001 ioc->spi_data.nvram = NULL; 2011 ioc->spi_data.nvram = NULL;
2002 ioc->spi_data.pIocPg3 = NULL; 2012 ioc->raid_data.pIocPg3 = NULL;
2003 2013
2004 if (ioc->spi_data.pIocPg4 != NULL) { 2014 if (ioc->spi_data.pIocPg4 != NULL) {
2005 sz = ioc->spi_data.IocPg4Sz; 2015 sz = ioc->spi_data.IocPg4Sz;
@@ -3852,7 +3862,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3852 int count = 0; 3862 int count = 0;
3853 u32 intstat=0; 3863 u32 intstat=0;
3854 3864
3855 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; 3865 cntdn = 1000 * howlong;
3856 3866
3857 if (sleepFlag == CAN_SLEEP) { 3867 if (sleepFlag == CAN_SLEEP) {
3858 while (--cntdn) { 3868 while (--cntdn) {
@@ -3902,7 +3912,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3902 int count = 0; 3912 int count = 0;
3903 u32 intstat=0; 3913 u32 intstat=0;
3904 3914
3905 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong; 3915 cntdn = 1000 * howlong;
3906 if (sleepFlag == CAN_SLEEP) { 3916 if (sleepFlag == CAN_SLEEP) {
3907 while (--cntdn) { 3917 while (--cntdn) {
3908 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 3918 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
@@ -4634,10 +4644,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4634 if (mpt_config(ioc, &cfg) != 0) 4644 if (mpt_config(ioc, &cfg) != 0)
4635 goto done_and_free; 4645 goto done_and_free;
4636 4646
4637 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) { 4647 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4638 mem = kmalloc(iocpage2sz, GFP_ATOMIC); 4648 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4639 if (mem) { 4649 if (mem) {
4640 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem; 4650 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4641 } else { 4651 } else {
4642 goto done_and_free; 4652 goto done_and_free;
4643 } 4653 }
@@ -4654,7 +4664,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4654 /* At least 1 RAID Volume 4664 /* At least 1 RAID Volume
4655 */ 4665 */
4656 pIocRv = pIoc2->RaidVolume; 4666 pIocRv = pIoc2->RaidVolume;
4657 ioc->spi_data.isRaid = 0; 4667 ioc->raid_data.isRaid = 0;
4658 for (jj = 0; jj < nVols; jj++, pIocRv++) { 4668 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4659 vid = pIocRv->VolumeID; 4669 vid = pIocRv->VolumeID;
4660 vbus = pIocRv->VolumeBus; 4670 vbus = pIocRv->VolumeBus;
@@ -4663,7 +4673,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4663 /* find the match 4673 /* find the match
4664 */ 4674 */
4665 if (vbus == 0) { 4675 if (vbus == 0) {
4666 ioc->spi_data.isRaid |= (1 << vid); 4676 ioc->raid_data.isRaid |= (1 << vid);
4667 } else { 4677 } else {
4668 /* Error! Always bus 0 4678 /* Error! Always bus 0
4669 */ 4679 */
@@ -4698,8 +4708,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4698 4708
4699 /* Free the old page 4709 /* Free the old page
4700 */ 4710 */
4701 kfree(ioc->spi_data.pIocPg3); 4711 kfree(ioc->raid_data.pIocPg3);
4702 ioc->spi_data.pIocPg3 = NULL; 4712 ioc->raid_data.pIocPg3 = NULL;
4703 4713
4704 /* There is at least one physical disk. 4714 /* There is at least one physical disk.
4705 * Read and save IOC Page 3 4715 * Read and save IOC Page 3
@@ -4736,7 +4746,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4736 mem = kmalloc(iocpage3sz, GFP_ATOMIC); 4746 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4737 if (mem) { 4747 if (mem) {
4738 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 4748 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4739 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem; 4749 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4740 } 4750 }
4741 } 4751 }
4742 4752
@@ -6022,6 +6032,111 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
6022 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); 6032 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6023} 6033}
6024 6034
6035/* strings for sas loginfo */
6036 static char *originator_str[] = {
6037 "IOP", /* 00h */
6038 "PL", /* 01h */
6039 "IR" /* 02h */
6040 };
6041 static char *iop_code_str[] = {
6042 NULL, /* 00h */
6043 "Invalid SAS Address", /* 01h */
6044 NULL, /* 02h */
6045 "Invalid Page", /* 03h */
6046 NULL, /* 04h */
6047 "Task Terminated" /* 05h */
6048 };
6049 static char *pl_code_str[] = {
6050 NULL, /* 00h */
6051 "Open Failure", /* 01h */
6052 "Invalid Scatter Gather List", /* 02h */
6053 "Wrong Relative Offset or Frame Length", /* 03h */
6054 "Frame Transfer Error", /* 04h */
6055 "Transmit Frame Connected Low", /* 05h */
6056 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6057 "SATA Read Log Receive Data Error", /* 07h */
6058 "SATA NCQ Fail All Commands After Error", /* 08h */
6059 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6060 "Receive Frame Invalid Message", /* 0Ah */
6061 "Receive Context Message Valid Error", /* 0Bh */
6062 "Receive Frame Current Frame Error", /* 0Ch */
6063 "SATA Link Down", /* 0Dh */
6064 "Discovery SATA Init W IOS", /* 0Eh */
6065 "Config Invalid Page", /* 0Fh */
6066 "Discovery SATA Init Timeout", /* 10h */
6067 "Reset", /* 11h */
6068 "Abort", /* 12h */
6069 "IO Not Yet Executed", /* 13h */
6070 "IO Executed", /* 14h */
6071 NULL, /* 15h */
6072 NULL, /* 16h */
6073 NULL, /* 17h */
6074 NULL, /* 18h */
6075 NULL, /* 19h */
6076 NULL, /* 1Ah */
6077 NULL, /* 1Bh */
6078 NULL, /* 1Ch */
6079 NULL, /* 1Dh */
6080 NULL, /* 1Eh */
6081 NULL, /* 1Fh */
6082 "Enclosure Management" /* 20h */
6083 };
6084
6085/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6086/*
6087 * mpt_sas_log_info - Log information returned from SAS IOC.
6088 * @ioc: Pointer to MPT_ADAPTER structure
6089 * @log_info: U32 LogInfo reply word from the IOC
6090 *
6091 * Refer to lsi/mpi_log_sas.h.
6092 */
6093static void
6094mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6095{
6096union loginfo_type {
6097 u32 loginfo;
6098 struct {
6099 u32 subcode:16;
6100 u32 code:8;
6101 u32 originator:4;
6102 u32 bus_type:4;
6103 }dw;
6104};
6105 union loginfo_type sas_loginfo;
6106 char *code_desc = NULL;
6107
6108 sas_loginfo.loginfo = log_info;
6109 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6110 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6111 return;
6112 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6113 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6114 code_desc = iop_code_str[sas_loginfo.dw.code];
6115 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6116 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6117 code_desc = pl_code_str[sas_loginfo.dw.code];
6118 }
6119
6120 if (code_desc != NULL)
6121 printk(MYIOC_s_INFO_FMT
6122 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6123 " SubCode(0x%04x)\n",
6124 ioc->name,
6125 log_info,
6126 originator_str[sas_loginfo.dw.originator],
6127 code_desc,
6128 sas_loginfo.dw.subcode);
6129 else
6130 printk(MYIOC_s_INFO_FMT
6131 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6132 " SubCode(0x%04x)\n",
6133 ioc->name,
6134 log_info,
6135 originator_str[sas_loginfo.dw.originator],
6136 sas_loginfo.dw.code,
6137 sas_loginfo.dw.subcode);
6138}
6139
6025/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6140/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6026/* 6141/*
6027 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC. 6142 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index bbd21d74ce5c..75105277e22f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -77,8 +77,8 @@
77#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 77#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
78#endif 78#endif
79 79
80#define MPT_LINUX_VERSION_COMMON "3.03.02" 80#define MPT_LINUX_VERSION_COMMON "3.03.03"
81#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02" 81#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
82#define WHAT_MAGIC_STRING "@" "(" "#" ")" 82#define WHAT_MAGIC_STRING "@" "(" "#" ")"
83 83
84#define show_mptmod_ver(s,ver) \ 84#define show_mptmod_ver(s,ver) \
@@ -424,7 +424,7 @@ typedef struct _MPT_IOCTL {
424/* 424/*
425 * Event Structure and define 425 * Event Structure and define
426 */ 426 */
427#define MPTCTL_EVENT_LOG_SIZE (0x0000000A) 427#define MPTCTL_EVENT_LOG_SIZE (0x000000032)
428typedef struct _mpt_ioctl_events { 428typedef struct _mpt_ioctl_events {
429 u32 event; /* Specified by define above */ 429 u32 event; /* Specified by define above */
430 u32 eventContext; /* Index or counter */ 430 u32 eventContext; /* Index or counter */
@@ -452,16 +452,13 @@ typedef struct _mpt_ioctl_events {
452#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */ 452#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
453/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ 453/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
454 454
455typedef struct _ScsiCfgData { 455typedef struct _SpiCfgData {
456 u32 PortFlags; 456 u32 PortFlags;
457 int *nvram; /* table of device NVRAM values */ 457 int *nvram; /* table of device NVRAM values */
458 IOCPage2_t *pIocPg2; /* table of Raid Volumes */
459 IOCPage3_t *pIocPg3; /* table of physical disks */
460 IOCPage4_t *pIocPg4; /* SEP devices addressing */ 458 IOCPage4_t *pIocPg4; /* SEP devices addressing */
461 dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ 459 dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
462 int IocPg4Sz; /* IOCPage4 size */ 460 int IocPg4Sz; /* IOCPage4 size */
463 u8 dvStatus[MPT_MAX_SCSI_DEVICES]; 461 u8 dvStatus[MPT_MAX_SCSI_DEVICES];
464 int isRaid; /* bit field, 1 if RAID */
465 u8 minSyncFactor; /* 0xFF if async */ 462 u8 minSyncFactor; /* 0xFF if async */
466 u8 maxSyncOffset; /* 0 if async */ 463 u8 maxSyncOffset; /* 0 if async */
467 u8 maxBusWidth; /* 0 if narrow, 1 if wide */ 464 u8 maxBusWidth; /* 0 if narrow, 1 if wide */
@@ -473,10 +470,14 @@ typedef struct _ScsiCfgData {
473 u8 dvScheduled; /* 1 if scheduled */ 470 u8 dvScheduled; /* 1 if scheduled */
474 u8 forceDv; /* 1 to force DV scheduling */ 471 u8 forceDv; /* 1 to force DV scheduling */
475 u8 noQas; /* Disable QAS for this adapter */ 472 u8 noQas; /* Disable QAS for this adapter */
476 u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */ 473 u8 Saf_Te; /* 1 to force all Processors as
474 * SAF-TE if Inquiry data length
475 * is too short to check for SAF-TE
476 */
477 u8 mpt_dv; /* command line option: enhanced=1, basic=0 */ 477 u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
478 u8 bus_reset; /* 1 to allow bus reset */
478 u8 rsvd[1]; 479 u8 rsvd[1];
479} ScsiCfgData; 480}SpiCfgData;
480 481
481typedef struct _SasCfgData { 482typedef struct _SasCfgData {
482 u8 ptClear; /* 1 to automatically clear the 483 u8 ptClear; /* 1 to automatically clear the
@@ -486,6 +487,12 @@ typedef struct _SasCfgData {
486 */ 487 */
487}SasCfgData; 488}SasCfgData;
488 489
490typedef struct _RaidCfgData {
491 IOCPage2_t *pIocPg2; /* table of Raid Volumes */
492 IOCPage3_t *pIocPg3; /* table of physical disks */
493 int isRaid; /* bit field, 1 if RAID */
494}RaidCfgData;
495
489/* 496/*
490 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 497 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
491 */ 498 */
@@ -546,7 +553,8 @@ typedef struct _MPT_ADAPTER
546 struct pci_dev *pcidev; /* struct pci_dev pointer */ 553 struct pci_dev *pcidev; /* struct pci_dev pointer */
547 u8 __iomem *memmap; /* mmap address */ 554 u8 __iomem *memmap; /* mmap address */
548 struct Scsi_Host *sh; /* Scsi Host pointer */ 555 struct Scsi_Host *sh; /* Scsi Host pointer */
549 ScsiCfgData spi_data; /* Scsi config. data */ 556 SpiCfgData spi_data; /* Scsi config. data */
557 RaidCfgData raid_data; /* Raid config. data */
550 SasCfgData sas_data; /* Sas config. data */ 558 SasCfgData sas_data; /* Sas config. data */
551 MPT_IOCTL *ioctl; /* ioctl data pointer */ 559 MPT_IOCTL *ioctl; /* ioctl data pointer */
552 struct proc_dir_entry *ioc_dentry; 560 struct proc_dir_entry *ioc_dentry;
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 7577c2417e2e..cb2d59d5f5af 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg)
1326 */ 1326 */
1327 if (hd && hd->Targets) { 1327 if (hd && hd->Targets) {
1328 mpt_findImVolumes(ioc); 1328 mpt_findImVolumes(ioc);
1329 pIoc2 = ioc->spi_data.pIocPg2; 1329 pIoc2 = ioc->raid_data.pIocPg2;
1330 for ( id = 0; id <= max_id; ) { 1330 for ( id = 0; id <= max_id; ) {
1331 if ( pIoc2 && pIoc2->NumActiveVolumes ) { 1331 if ( pIoc2 && pIoc2->NumActiveVolumes ) {
1332 if ( id == pIoc2->RaidVolume[0].VolumeID ) { 1332 if ( id == pIoc2->RaidVolume[0].VolumeID ) {
@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg)
1348 --maxWordsLeft; 1348 --maxWordsLeft;
1349 goto next_id; 1349 goto next_id;
1350 } else { 1350 } else {
1351 pIoc3 = ioc->spi_data.pIocPg3; 1351 pIoc3 = ioc->raid_data.pIocPg3;
1352 for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) { 1352 for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
1353 if ( pIoc3->PhysDisk[jj].PhysDiskID == id ) 1353 if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
1354 goto next_id; 1354 goto next_id;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 13771abea13f..a628be9bbbad 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
189 printk(MYIOC_s_WARN_FMT 189 printk(MYIOC_s_WARN_FMT
190 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 190 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
191 ioc->name, ioc); 191 ioc->name, ioc);
192 return -ENODEV; 192 return 0;
193 } 193 }
194 194
195 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 195 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 52794be5a95c..ed3c891e388f 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -312,7 +312,12 @@ static int
312mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 312mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
313{ 313{
314 struct net_device *dev = ioc->netdev; 314 struct net_device *dev = ioc->netdev;
315 struct mpt_lan_priv *priv = netdev_priv(dev); 315 struct mpt_lan_priv *priv;
316
317 if (dev == NULL)
318 return(1);
319 else
320 priv = netdev_priv(dev);
316 321
317 dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", 322 dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
318 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( 323 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 0d9a192e1bd4..429820e48c69 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -980,7 +980,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
980 printk(MYIOC_s_WARN_FMT 980 printk(MYIOC_s_WARN_FMT
981 "Skipping ioc=%p because SCSI Initiator mode " 981 "Skipping ioc=%p because SCSI Initiator mode "
982 "is NOT enabled!\n", ioc->name, ioc); 982 "is NOT enabled!\n", ioc->name, ioc);
983 return -ENODEV; 983 return 0;
984 } 984 }
985 985
986 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST)); 986 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 58b5fdee009a..8dd25aac5355 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -93,8 +93,9 @@ typedef struct _BIG_SENSE_BUF {
93 93
94#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ 94#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
95#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ 95#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
96#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */ 96#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
97#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */ 97#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
98#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
98#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ 99#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
99#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ 100#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
100 101
@@ -159,6 +160,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
159static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 160static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
160static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); 161static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
161 162
163static struct work_struct mptscsih_persistTask;
164
162#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 165#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
163static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); 166static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
164static void mptscsih_domainValidation(void *hd); 167static void mptscsih_domainValidation(void *hd);
@@ -167,6 +170,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
167static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); 170static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
168static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); 171static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
169static void mptscsih_fillbuf(char *buffer, int size, int index, int width); 172static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
173static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
170#endif 174#endif
171 175
172void mptscsih_remove(struct pci_dev *); 176void mptscsih_remove(struct pci_dev *);
@@ -606,11 +610,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
606 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); 610 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
607 sc->resid = sc->request_bufflen - xfer_cnt; 611 sc->resid = sc->request_bufflen - xfer_cnt;
608 612
613 /*
614 * if we get a data underrun indication, yet no data was
615 * transferred and the SCSI status indicates that the
616 * command was never started, change the data underrun
617 * to success
618 */
619 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
620 (scsi_status == MPI_SCSI_STATUS_BUSY ||
621 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
622 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
623 status = MPI_IOCSTATUS_SUCCESS;
624 }
625
609 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" 626 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
610 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" 627 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
611 "resid=%d bufflen=%d xfer_cnt=%d\n", 628 "resid=%d bufflen=%d xfer_cnt=%d\n",
612 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], 629 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
613 status, scsi_state, scsi_status, sc->resid, 630 status, scsi_state, scsi_status, sc->resid,
614 sc->request_bufflen, xfer_cnt)); 631 sc->request_bufflen, xfer_cnt));
615 632
616 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) 633 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
@@ -619,8 +636,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
619 /* 636 /*
620 * Look for + dump FCP ResponseInfo[]! 637 * Look for + dump FCP ResponseInfo[]!
621 */ 638 */
622 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) { 639 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
623 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n", 640 pScsiReply->ResponseInfo) {
641 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
642 "FCP_ResponseInfo=%08xh\n",
643 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
624 le32_to_cpu(pScsiReply->ResponseInfo)); 644 le32_to_cpu(pScsiReply->ResponseInfo));
625 } 645 }
626 646
@@ -661,23 +681,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
661 break; 681 break;
662 682
663 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 683 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
664 if ( xfer_cnt >= sc->underflow ) { 684 sc->resid = sc->request_bufflen - xfer_cnt;
665 /* Sufficient data transfer occurred */ 685 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
686 sc->result=DID_SOFT_ERROR << 16;
687 else /* Sufficient data transfer occurred */
666 sc->result = (DID_OK << 16) | scsi_status; 688 sc->result = (DID_OK << 16) | scsi_status;
667 } else if ( xfer_cnt == 0 ) { 689 dreplyprintk((KERN_NOTICE
668 /* A CRC Error causes this condition; retry */ 690 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
669 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
670 (CHECK_CONDITION << 1);
671 sc->sense_buffer[0] = 0x70;
672 sc->sense_buffer[2] = NO_SENSE;
673 sc->sense_buffer[12] = 0;
674 sc->sense_buffer[13] = 0;
675 } else {
676 sc->result = DID_SOFT_ERROR << 16;
677 }
678 dreplyprintk((KERN_NOTICE
679 "RESIDUAL_MISMATCH: result=%x on id=%d\n",
680 sc->result, sc->device->id));
681 break; 691 break;
682 692
683 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 693 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -692,7 +702,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
692 ; 702 ;
693 } else { 703 } else {
694 if (xfer_cnt < sc->underflow) { 704 if (xfer_cnt < sc->underflow) {
695 sc->result = DID_SOFT_ERROR << 16; 705 if (scsi_status == SAM_STAT_BUSY)
706 sc->result = SAM_STAT_BUSY;
707 else
708 sc->result = DID_SOFT_ERROR << 16;
696 } 709 }
697 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { 710 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
698 /* What to do? 711 /* What to do?
@@ -717,8 +730,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
717 730
718 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 731 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
719 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ 732 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
720 scsi_status = pScsiReply->SCSIStatus; 733 if (scsi_status == MPI_SCSI_STATUS_BUSY)
721 sc->result = (DID_OK << 16) | scsi_status; 734 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
735 else
736 sc->result = (DID_OK << 16) | scsi_status;
722 if (scsi_state == 0) { 737 if (scsi_state == 0) {
723 ; 738 ;
724 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 739 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -890,12 +905,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
890 SCSIIORequest_t *mf = NULL; 905 SCSIIORequest_t *mf = NULL;
891 int ii; 906 int ii;
892 int max = hd->ioc->req_depth; 907 int max = hd->ioc->req_depth;
908 struct scsi_cmnd *sc;
893 909
894 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", 910 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
895 target, lun, max)); 911 target, lun, max));
896 912
897 for (ii=0; ii < max; ii++) { 913 for (ii=0; ii < max; ii++) {
898 if (hd->ScsiLookup[ii] != NULL) { 914 if ((sc = hd->ScsiLookup[ii]) != NULL) {
899 915
900 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); 916 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
901 917
@@ -910,9 +926,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
910 hd->ScsiLookup[ii] = NULL; 926 hd->ScsiLookup[ii] = NULL;
911 mptscsih_freeChainBuffers(hd->ioc, ii); 927 mptscsih_freeChainBuffers(hd->ioc, ii);
912 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); 928 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
929 if (sc->use_sg) {
930 pci_unmap_sg(hd->ioc->pcidev,
931 (struct scatterlist *) sc->request_buffer,
932 sc->use_sg,
933 sc->sc_data_direction);
934 } else if (sc->request_bufflen) {
935 pci_unmap_single(hd->ioc->pcidev,
936 sc->SCp.dma_handle,
937 sc->request_bufflen,
938 sc->sc_data_direction);
939 }
940 sc->host_scribble = NULL;
941 sc->result = DID_NO_CONNECT << 16;
942 sc->scsi_done(sc);
913 } 943 }
914 } 944 }
915
916 return; 945 return;
917} 946}
918 947
@@ -967,8 +996,10 @@ mptscsih_remove(struct pci_dev *pdev)
967 unsigned long flags; 996 unsigned long flags;
968 int sz1; 997 int sz1;
969 998
970 if(!host) 999 if(!host) {
1000 mpt_detach(pdev);
971 return; 1001 return;
1002 }
972 1003
973 scsi_remove_host(host); 1004 scsi_remove_host(host);
974 1005
@@ -1422,6 +1453,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1422 return 0; 1453 return 0;
1423 1454
1424 fail: 1455 fail:
1456 hd->ScsiLookup[my_idx] = NULL;
1425 mptscsih_freeChainBuffers(hd->ioc, my_idx); 1457 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1426 mpt_free_msg_frame(hd->ioc, mf); 1458 mpt_free_msg_frame(hd->ioc, mf);
1427 return SCSI_MLQUEUE_HOST_BUSY; 1459 return SCSI_MLQUEUE_HOST_BUSY;
@@ -1709,24 +1741,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1709 MPT_FRAME_HDR *mf; 1741 MPT_FRAME_HDR *mf;
1710 u32 ctx2abort; 1742 u32 ctx2abort;
1711 int scpnt_idx; 1743 int scpnt_idx;
1744 int retval;
1712 1745
1713 /* If we can't locate our host adapter structure, return FAILED status. 1746 /* If we can't locate our host adapter structure, return FAILED status.
1714 */ 1747 */
1715 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { 1748 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1716 SCpnt->result = DID_RESET << 16; 1749 SCpnt->result = DID_RESET << 16;
1717 SCpnt->scsi_done(SCpnt); 1750 SCpnt->scsi_done(SCpnt);
1718 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: " 1751 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1719 "Can't locate host! (sc=%p)\n", 1752 "Can't locate host! (sc=%p)\n",
1720 SCpnt)); 1753 SCpnt));
1721 return FAILED; 1754 return FAILED;
1722 } 1755 }
1723 1756
1724 ioc = hd->ioc; 1757 ioc = hd->ioc;
1725 if (hd->resetPending) 1758 if (hd->resetPending) {
1726 return FAILED; 1759 return FAILED;
1727 1760 }
1728 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
1729 hd->ioc->name, SCpnt);
1730 1761
1731 if (hd->timeouts < -1) 1762 if (hd->timeouts < -1)
1732 hd->timeouts++; 1763 hd->timeouts++;
@@ -1734,16 +1765,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1734 /* Find this command 1765 /* Find this command
1735 */ 1766 */
1736 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { 1767 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1737 /* Cmd not found in ScsiLookup. 1768 /* Cmd not found in ScsiLookup.
1738 * Do OS callback. 1769 * Do OS callback.
1739 */ 1770 */
1740 SCpnt->result = DID_RESET << 16; 1771 SCpnt->result = DID_RESET << 16;
1741 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " 1772 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1742 "Command not in the active list! (sc=%p)\n", 1773 "Command not in the active list! (sc=%p)\n",
1743 hd->ioc->name, SCpnt)); 1774 hd->ioc->name, SCpnt));
1744 return SUCCESS; 1775 return SUCCESS;
1745 } 1776 }
1746 1777
1778 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1779 hd->ioc->name, SCpnt);
1780 scsi_print_command(SCpnt);
1781
1747 /* Most important! Set TaskMsgContext to SCpnt's MsgContext! 1782 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1748 * (the IO to be ABORT'd) 1783 * (the IO to be ABORT'd)
1749 * 1784 *
@@ -1756,38 +1791,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1756 1791
1757 hd->abortSCpnt = SCpnt; 1792 hd->abortSCpnt = SCpnt;
1758 1793
1759 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1794 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1760 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, 1795 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1761 ctx2abort, 2 /* 2 second timeout */) 1796 ctx2abort, 2 /* 2 second timeout */);
1762 < 0) {
1763 1797
1764 /* The TM request failed and the subsequent FW-reload failed! 1798 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1765 * Fatal error case. 1799 hd->ioc->name,
1766 */ 1800 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1767 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
1768 hd->ioc->name, SCpnt);
1769 1801
1770 /* We must clear our pending flag before clearing our state. 1802 if (retval == 0)
1771 */ 1803 return SUCCESS;
1804
1805 if(retval != FAILED ) {
1772 hd->tmPending = 0; 1806 hd->tmPending = 0;
1773 hd->tmState = TM_STATE_NONE; 1807 hd->tmState = TM_STATE_NONE;
1774
1775 /* Unmap the DMA buffers, if any. */
1776 if (SCpnt->use_sg) {
1777 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
1778 SCpnt->use_sg, SCpnt->sc_data_direction);
1779 } else if (SCpnt->request_bufflen) {
1780 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
1781 SCpnt->request_bufflen, SCpnt->sc_data_direction);
1782 }
1783 hd->ScsiLookup[scpnt_idx] = NULL;
1784 SCpnt->result = DID_RESET << 16;
1785 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1786 mptscsih_freeChainBuffers(ioc, scpnt_idx);
1787 mpt_free_msg_frame(ioc, mf);
1788 return FAILED;
1789 } 1808 }
1790 return SUCCESS; 1809 return FAILED;
1791} 1810}
1792 1811
1793/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1812/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1803,11 +1822,12 @@ int
1803mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1822mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1804{ 1823{
1805 MPT_SCSI_HOST *hd; 1824 MPT_SCSI_HOST *hd;
1825 int retval;
1806 1826
1807 /* If we can't locate our host adapter structure, return FAILED status. 1827 /* If we can't locate our host adapter structure, return FAILED status.
1808 */ 1828 */
1809 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1829 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1810 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: " 1830 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1811 "Can't locate host! (sc=%p)\n", 1831 "Can't locate host! (sc=%p)\n",
1812 SCpnt)); 1832 SCpnt));
1813 return FAILED; 1833 return FAILED;
@@ -1816,24 +1836,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1816 if (hd->resetPending) 1836 if (hd->resetPending)
1817 return FAILED; 1837 return FAILED;
1818 1838
1819 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", 1839 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1820 hd->ioc->name, SCpnt); 1840 hd->ioc->name, SCpnt);
1841 scsi_print_command(SCpnt);
1821 1842
1822 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1843 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1823 SCpnt->device->channel, SCpnt->device->id, 1844 SCpnt->device->channel, SCpnt->device->id,
1824 0, 0, 5 /* 5 second timeout */) 1845 0, 0, 5 /* 5 second timeout */);
1825 < 0){ 1846
1826 /* The TM request failed and the subsequent FW-reload failed! 1847 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1827 * Fatal error case. 1848 hd->ioc->name,
1828 */ 1849 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1829 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n", 1850
1830 hd->ioc->name, SCpnt); 1851 if (retval == 0)
1852 return SUCCESS;
1853
1854 if(retval != FAILED ) {
1831 hd->tmPending = 0; 1855 hd->tmPending = 0;
1832 hd->tmState = TM_STATE_NONE; 1856 hd->tmState = TM_STATE_NONE;
1833 return FAILED;
1834 } 1857 }
1835 1858 return FAILED;
1836 return SUCCESS;
1837} 1859}
1838 1860
1839/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1861/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1849,41 +1871,39 @@ int
1849mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1871mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1850{ 1872{
1851 MPT_SCSI_HOST *hd; 1873 MPT_SCSI_HOST *hd;
1852 spinlock_t *host_lock = SCpnt->device->host->host_lock; 1874 int retval;
1853 1875
1854 /* If we can't locate our host adapter structure, return FAILED status. 1876 /* If we can't locate our host adapter structure, return FAILED status.
1855 */ 1877 */
1856 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1878 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1857 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: " 1879 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1858 "Can't locate host! (sc=%p)\n", 1880 "Can't locate host! (sc=%p)\n",
1859 SCpnt ) ); 1881 SCpnt ) );
1860 return FAILED; 1882 return FAILED;
1861 } 1883 }
1862 1884
1863 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n", 1885 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1864 hd->ioc->name, SCpnt); 1886 hd->ioc->name, SCpnt);
1887 scsi_print_command(SCpnt);
1865 1888
1866 if (hd->timeouts < -1) 1889 if (hd->timeouts < -1)
1867 hd->timeouts++; 1890 hd->timeouts++;
1868 1891
1869 /* We are now ready to execute the task management request. */ 1892 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1870 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1893 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
1871 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
1872 < 0){
1873 1894
1874 /* The TM request failed and the subsequent FW-reload failed! 1895 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1875 * Fatal error case. 1896 hd->ioc->name,
1876 */ 1897 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1877 printk(MYIOC_s_WARN_FMT 1898
1878 "Error processing TaskMgmt request (sc=%p)\n", 1899 if (retval == 0)
1879 hd->ioc->name, SCpnt); 1900 return SUCCESS;
1901
1902 if(retval != FAILED ) {
1880 hd->tmPending = 0; 1903 hd->tmPending = 0;
1881 hd->tmState = TM_STATE_NONE; 1904 hd->tmState = TM_STATE_NONE;
1882 spin_lock_irq(host_lock);
1883 return FAILED;
1884 } 1905 }
1885 1906 return FAILED;
1886 return SUCCESS;
1887} 1907}
1888 1908
1889/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1909/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2165,7 +2185,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
2165 vdev->raidVolume = 0; 2185 vdev->raidVolume = 0;
2166 hd->Targets[device->id] = vdev; 2186 hd->Targets[device->id] = vdev;
2167 if (hd->ioc->bus_type == SCSI) { 2187 if (hd->ioc->bus_type == SCSI) {
2168 if (hd->ioc->spi_data.isRaid & (1 << device->id)) { 2188 if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
2169 vdev->raidVolume = 1; 2189 vdev->raidVolume = 1;
2170 ddvtprintk((KERN_INFO 2190 ddvtprintk((KERN_INFO
2171 "RAID Volume @ id %d\n", device->id)); 2191 "RAID Volume @ id %d\n", device->id));
@@ -2180,22 +2200,6 @@ mptscsih_slave_alloc(struct scsi_device *device)
2180 return 0; 2200 return 0;
2181} 2201}
2182 2202
2183static int
2184mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2185{
2186 int i;
2187
2188 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2189 return 0;
2190
2191 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2192 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2193 return 1;
2194 }
2195
2196 return 0;
2197}
2198
2199/* 2203/*
2200 * OS entry point to allow for host driver to free allocated memory 2204 * OS entry point to allow for host driver to free allocated memory
2201 * Called if no device present or device being unloaded 2205 * Called if no device present or device being unloaded
@@ -2223,7 +2227,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
2223 hd->Targets[target] = NULL; 2227 hd->Targets[target] = NULL;
2224 2228
2225 if (hd->ioc->bus_type == SCSI) { 2229 if (hd->ioc->bus_type == SCSI) {
2226 if (mptscsih_is_raid_volume(hd, target)) { 2230 if (mptscsih_is_phys_disk(hd->ioc, target)) {
2227 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; 2231 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2228 } else { 2232 } else {
2229 hd->ioc->spi_data.dvStatus[target] = 2233 hd->ioc->spi_data.dvStatus[target] =
@@ -2436,6 +2440,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2436{ 2440{
2437 MPT_SCSI_HOST *hd; 2441 MPT_SCSI_HOST *hd;
2438 unsigned long flags; 2442 unsigned long flags;
2443 int ii;
2439 2444
2440 dtmprintk((KERN_WARNING MYNAM 2445 dtmprintk((KERN_WARNING MYNAM
2441 ": IOC %s_reset routed to SCSI host driver!\n", 2446 ": IOC %s_reset routed to SCSI host driver!\n",
@@ -2493,11 +2498,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2493 2498
2494 /* ScsiLookup initialization 2499 /* ScsiLookup initialization
2495 */ 2500 */
2496 { 2501 for (ii=0; ii < hd->ioc->req_depth; ii++)
2497 int ii; 2502 hd->ScsiLookup[ii] = NULL;
2498 for (ii=0; ii < hd->ioc->req_depth; ii++)
2499 hd->ScsiLookup[ii] = NULL;
2500 }
2501 2503
2502 /* 2. Chain Buffer initialization 2504 /* 2. Chain Buffer initialization
2503 */ 2505 */
@@ -2546,6 +2548,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2546} 2548}
2547 2549
2548/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2550/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2551/* work queue thread to clear the persitency table */
2552static void
2553mptscsih_sas_persist_clear_table(void * arg)
2554{
2555 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2556
2557 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2558}
2559
2560/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2549int 2561int
2550mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) 2562mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2551{ 2563{
@@ -2555,18 +2567,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2555 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2567 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2556 ioc->name, event)); 2568 ioc->name, event));
2557 2569
2570 if (ioc->sh == NULL ||
2571 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2572 return 1;
2573
2558 switch (event) { 2574 switch (event) {
2559 case MPI_EVENT_UNIT_ATTENTION: /* 03 */ 2575 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2560 /* FIXME! */ 2576 /* FIXME! */
2561 break; 2577 break;
2562 case MPI_EVENT_IOC_BUS_RESET: /* 04 */ 2578 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2563 case MPI_EVENT_EXT_BUS_RESET: /* 05 */ 2579 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2564 hd = NULL; 2580 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2565 if (ioc->sh) { 2581 hd->soft_resets++;
2566 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2567 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2568 hd->soft_resets++;
2569 }
2570 break; 2582 break;
2571 case MPI_EVENT_LOGOUT: /* 09 */ 2583 case MPI_EVENT_LOGOUT: /* 09 */
2572 /* FIXME! */ 2584 /* FIXME! */
@@ -2585,69 +2597,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2585 break; 2597 break;
2586 2598
2587 case MPI_EVENT_INTEGRATED_RAID: /* 0B */ 2599 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2600 {
2601 pMpiEventDataRaid_t pRaidEventData =
2602 (pMpiEventDataRaid_t) pEvReply->Data;
2588#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 2603#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2589 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if 2604 /* Domain Validation Needed */
2590 * if DV disabled. Need to check for target mode. 2605 if (ioc->bus_type == SCSI &&
2591 */ 2606 pRaidEventData->ReasonCode ==
2592 hd = NULL; 2607 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2593 if (ioc->sh) 2608 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2594 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2595
2596 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
2597 ScsiCfgData *pSpi;
2598 Ioc3PhysDisk_t *pPDisk;
2599 int numPDisk;
2600 u8 reason;
2601 u8 physDiskNum;
2602
2603 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
2604 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
2605 /* New or replaced disk.
2606 * Set DV flag and schedule DV.
2607 */
2608 pSpi = &ioc->spi_data;
2609 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
2610 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
2611 if (pSpi->pIocPg3) {
2612 pPDisk = pSpi->pIocPg3->PhysDisk;
2613 numPDisk =pSpi->pIocPg3->NumPhysDisks;
2614
2615 while (numPDisk) {
2616 if (physDiskNum == pPDisk->PhysDiskNum) {
2617 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2618 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2619 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2620 break;
2621 }
2622 pPDisk++;
2623 numPDisk--;
2624 }
2625
2626 if (numPDisk == 0) {
2627 /* The physical disk that needs DV was not found
2628 * in the stored IOC Page 3. The driver must reload
2629 * this page. DV routine will set the NEED_DV flag for
2630 * all phys disks that have DV_NOT_DONE set.
2631 */
2632 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2633 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
2634 }
2635 }
2636 }
2637 }
2638#endif 2609#endif
2610 break;
2611 }
2639 2612
2640#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) 2613 /* Persistent table is full. */
2641 printk("Raid Event RF: "); 2614 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2642 { 2615 INIT_WORK(&mptscsih_persistTask,
2643 u32 *m = (u32 *)pEvReply; 2616 mptscsih_sas_persist_clear_table,(void *)ioc);
2644 int ii; 2617 schedule_work(&mptscsih_persistTask);
2645 int n = (int)pEvReply->MsgLength;
2646 for (ii=6; ii < n; ii++)
2647 printk(" %08x", le32_to_cpu(m[ii]));
2648 printk("\n");
2649 }
2650#endif
2651 break; 2618 break;
2652 2619
2653 case MPI_EVENT_NONE: /* 00 */ 2620 case MPI_EVENT_NONE: /* 00 */
@@ -2684,7 +2651,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
2684{ 2651{
2685 int indexed_lun, lun_index; 2652 int indexed_lun, lun_index;
2686 VirtDevice *vdev; 2653 VirtDevice *vdev;
2687 ScsiCfgData *pSpi; 2654 SpiCfgData *pSpi;
2688 char data_56; 2655 char data_56;
2689 2656
2690 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", 2657 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
@@ -2791,7 +2758,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
2791static void 2758static void
2792mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) 2759mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2793{ 2760{
2794 ScsiCfgData *pspi_data = &hd->ioc->spi_data; 2761 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2795 int id = (int) target->target_id; 2762 int id = (int) target->target_id;
2796 int nvram; 2763 int nvram;
2797 VirtDevice *vdev; 2764 VirtDevice *vdev;
@@ -2970,11 +2937,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2970static void 2937static void
2971mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) 2938mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2972{ 2939{
2940 MPT_ADAPTER *ioc = hd->ioc;
2973 u8 cmd; 2941 u8 cmd;
2974 ScsiCfgData *pSpi; 2942 SpiCfgData *pSpi;
2975 2943
2976 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", 2944 ddvtprintk((MYIOC_s_NOTE_FMT
2977 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); 2945 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2946 hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2978 2947
2979 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) 2948 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2980 return; 2949 return;
@@ -2982,12 +2951,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2982 cmd = pReq->CDB[0]; 2951 cmd = pReq->CDB[0];
2983 2952
2984 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { 2953 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2985 pSpi = &hd->ioc->spi_data; 2954 pSpi = &ioc->spi_data;
2986 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) { 2955 if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
2987 /* Set NEED_DV for all hidden disks 2956 /* Set NEED_DV for all hidden disks
2988 */ 2957 */
2989 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk; 2958 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2990 int numPDisk = pSpi->pIocPg3->NumPhysDisks; 2959 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2991 2960
2992 while (numPDisk) { 2961 while (numPDisk) {
2993 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; 2962 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
@@ -3001,6 +2970,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3001 } 2970 }
3002} 2971}
3003 2972
2973/* mptscsih_raid_set_dv_flags()
2974 *
2975 * New or replaced disk. Set DV flag and schedule DV.
2976 */
2977static void
2978mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
2979{
2980 MPT_ADAPTER *ioc = hd->ioc;
2981 SpiCfgData *pSpi = &ioc->spi_data;
2982 Ioc3PhysDisk_t *pPDisk;
2983 int numPDisk;
2984
2985 if (hd->negoNvram != 0)
2986 return;
2987
2988 ddvtprintk(("DV requested for phys disk id %d\n", id));
2989 if (ioc->raid_data.pIocPg3) {
2990 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2991 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2992 while (numPDisk) {
2993 if (id == pPDisk->PhysDiskNum) {
2994 pSpi->dvStatus[pPDisk->PhysDiskID] =
2995 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2996 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2997 ddvtprintk(("NEED_DV set for phys disk id %d\n",
2998 pPDisk->PhysDiskID));
2999 break;
3000 }
3001 pPDisk++;
3002 numPDisk--;
3003 }
3004
3005 if (numPDisk == 0) {
3006 /* The physical disk that needs DV was not found
3007 * in the stored IOC Page 3. The driver must reload
3008 * this page. DV routine will set the NEED_DV flag for
3009 * all phys disks that have DV_NOT_DONE set.
3010 */
3011 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3012 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
3013 }
3014 }
3015}
3016
3004/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3017/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3005/* 3018/*
3006 * If no Target, bus reset on 1st I/O. Set the flag to 3019 * If no Target, bus reset on 1st I/O. Set the flag to
@@ -3088,7 +3101,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3088 MPT_ADAPTER *ioc = hd->ioc; 3101 MPT_ADAPTER *ioc = hd->ioc;
3089 Config_t *pReq; 3102 Config_t *pReq;
3090 SCSIDevicePage1_t *pData; 3103 SCSIDevicePage1_t *pData;
3091 VirtDevice *pTarget; 3104 VirtDevice *pTarget=NULL;
3092 MPT_FRAME_HDR *mf; 3105 MPT_FRAME_HDR *mf;
3093 dma_addr_t dataDma; 3106 dma_addr_t dataDma;
3094 u16 req_idx; 3107 u16 req_idx;
@@ -3187,7 +3200,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3187#endif 3200#endif
3188 3201
3189 if (flags & MPT_SCSICFG_BLK_NEGO) 3202 if (flags & MPT_SCSICFG_BLK_NEGO)
3190 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC; 3203 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3191 3204
3192 mptscsih_setDevicePage1Flags(width, factor, offset, 3205 mptscsih_setDevicePage1Flags(width, factor, offset,
3193 &requested, &configuration, negoFlags); 3206 &requested, &configuration, negoFlags);
@@ -4008,7 +4021,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4008 4021
4009 /* If target Ptr NULL or if this target is NOT a disk, skip. 4022 /* If target Ptr NULL or if this target is NOT a disk, skip.
4010 */ 4023 */
4011 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){ 4024 if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
4012 for (lun=0; lun <= MPT_LAST_LUN; lun++) { 4025 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4013 /* If LUN present, issue the command 4026 /* If LUN present, issue the command
4014 */ 4027 */
@@ -4103,9 +4116,9 @@ mptscsih_domainValidation(void *arg)
4103 4116
4104 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) { 4117 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4105 mpt_read_ioc_pg_3(ioc); 4118 mpt_read_ioc_pg_3(ioc);
4106 if (ioc->spi_data.pIocPg3) { 4119 if (ioc->raid_data.pIocPg3) {
4107 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; 4120 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4108 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; 4121 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4109 4122
4110 while (numPDisk) { 4123 while (numPDisk) {
4111 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE) 4124 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
@@ -4144,7 +4157,7 @@ mptscsih_domainValidation(void *arg)
4144 isPhysDisk = mptscsih_is_phys_disk(ioc, id); 4157 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4145 if (isPhysDisk) { 4158 if (isPhysDisk) {
4146 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4159 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4147 if (hd->ioc->spi_data.isRaid & (1 << ii)) { 4160 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4148 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING; 4161 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4149 } 4162 }
4150 } 4163 }
@@ -4163,7 +4176,7 @@ mptscsih_domainValidation(void *arg)
4163 4176
4164 if (isPhysDisk) { 4177 if (isPhysDisk) {
4165 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4178 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4166 if (hd->ioc->spi_data.isRaid & (1 << ii)) { 4179 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4167 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING; 4180 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4168 } 4181 }
4169 } 4182 }
@@ -4185,21 +4198,21 @@ mptscsih_domainValidation(void *arg)
4185 4198
4186/* Search IOC page 3 to determine if this is hidden physical disk 4199/* Search IOC page 3 to determine if this is hidden physical disk
4187 */ 4200 */
4188static int 4201/* Search IOC page 3 to determine if this is hidden physical disk
4202 */
4203static int
4189mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 4204mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4190{ 4205{
4191 if (ioc->spi_data.pIocPg3) { 4206 int i;
4192 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4193 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4194 4207
4195 while (numPDisk) { 4208 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
4196 if (pPDisk->PhysDiskID == id) { 4209 return 0;
4197 return 1; 4210
4198 } 4211 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
4199 pPDisk++; 4212 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
4200 numPDisk--; 4213 return 1;
4201 }
4202 } 4214 }
4215
4203 return 0; 4216 return 0;
4204} 4217}
4205 4218
@@ -4405,7 +4418,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4405 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write 4418 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4406 */ 4419 */
4407 { 4420 {
4408 ScsiCfgData *pspi_data = &hd->ioc->spi_data; 4421 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4409 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { 4422 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4410 /* Set the factor from nvram */ 4423 /* Set the factor from nvram */
4411 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; 4424 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
@@ -4435,11 +4448,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4435 } 4448 }
4436 4449
4437 /* Finish iocmd inititialization - hidden or visible disk? */ 4450 /* Finish iocmd inititialization - hidden or visible disk? */
4438 if (ioc->spi_data.pIocPg3) { 4451 if (ioc->raid_data.pIocPg3) {
4439 /* Search IOC page 3 for matching id 4452 /* Search IOC page 3 for matching id
4440 */ 4453 */
4441 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; 4454 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4442 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; 4455 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4443 4456
4444 while (numPDisk) { 4457 while (numPDisk) {
4445 if (pPDisk->PhysDiskID == id) { 4458 if (pPDisk->PhysDiskID == id) {
@@ -4463,7 +4476,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4463 /* RAID Volume ID's may double for a physical device. If RAID but 4476 /* RAID Volume ID's may double for a physical device. If RAID but
4464 * not a physical ID as well, skip DV. 4477 * not a physical ID as well, skip DV.
4465 */ 4478 */
4466 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK)) 4479 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4467 goto target_done; 4480 goto target_done;
4468 4481
4469 4482
@@ -4812,6 +4825,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4812 notDone = 0; 4825 notDone = 0;
4813 if (iocmd.flags & MPT_ICFLAG_ECHO) { 4826 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4814 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3]; 4827 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4828 if (pbuf1[0] & 0x01)
4829 iocmd.flags |= MPT_ICFLAG_EBOS;
4815 } else { 4830 } else {
4816 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3]; 4831 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4817 } 4832 }
@@ -4908,6 +4923,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4908 } 4923 }
4909 iocmd.flags &= ~MPT_ICFLAG_DID_RESET; 4924 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4910 4925
4926 if (iocmd.flags & MPT_ICFLAG_EBOS)
4927 goto skip_Reserve;
4928
4911 repeat = 5; 4929 repeat = 5;
4912 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) { 4930 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4913 iocmd.cmd = RESERVE; 4931 iocmd.cmd = RESERVE;
@@ -4951,6 +4969,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4951 } 4969 }
4952 } 4970 }
4953 4971
4972skip_Reserve:
4954 mptscsih_fillbuf(pbuf1, sz, patt, 1); 4973 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4955 iocmd.cmd = WRITE_BUFFER; 4974 iocmd.cmd = WRITE_BUFFER;
4956 iocmd.data_dma = buf1_dma; 4975 iocmd.data_dma = buf1_dma;
@@ -5195,11 +5214,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5195 * If not an LVD bus, the adapter minSyncFactor has been 5214 * If not an LVD bus, the adapter minSyncFactor has been
5196 * already throttled back. 5215 * already throttled back.
5197 */ 5216 */
5217 negoFlags = hd->ioc->spi_data.noQas;
5198 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { 5218 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5199 width = pTarget->maxWidth; 5219 width = pTarget->maxWidth;
5200 offset = pTarget->maxOffset; 5220 offset = pTarget->maxOffset;
5201 factor = pTarget->minSyncFactor; 5221 factor = pTarget->minSyncFactor;
5202 negoFlags = pTarget->negoFlags; 5222 negoFlags |= pTarget->negoFlags;
5203 } else { 5223 } else {
5204 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { 5224 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5205 data = hd->ioc->spi_data.nvram[id]; 5225 data = hd->ioc->spi_data.nvram[id];
@@ -5220,7 +5240,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5220 } 5240 }
5221 5241
5222 /* Set the negotiation flags */ 5242 /* Set the negotiation flags */
5223 negoFlags = hd->ioc->spi_data.noQas;
5224 if (!width) 5243 if (!width)
5225 negoFlags |= MPT_TARGET_NO_NEGO_WIDE; 5244 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5226 5245
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 51c0255ac16e..09389af9845e 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/message/fusion/mptscsi.h 2 * linux/drivers/message/fusion/mptscsih.h
3 * High performance SCSI / Fibre Channel SCSI Host device driver. 3 * High performance SCSI / Fibre Channel SCSI Host device driver.
4 * For use with PCI chip/adapter(s): 4 * For use with PCI chip/adapter(s):
5 * LSIFC9xx/LSI409xx Fibre Channel 5 * LSIFC9xx/LSI409xx Fibre Channel
@@ -53,8 +53,8 @@
53 * SCSI Public stuff... 53 * SCSI Public stuff...
54 */ 54 */
55 55
56#define MPT_SCSI_CMD_PER_DEV_HIGH 31 56#define MPT_SCSI_CMD_PER_DEV_HIGH 64
57#define MPT_SCSI_CMD_PER_DEV_LOW 7 57#define MPT_SCSI_CMD_PER_DEV_LOW 32
58 58
59#define MPT_SCSI_CMD_PER_LUN 7 59#define MPT_SCSI_CMD_PER_LUN 7
60 60
@@ -77,6 +77,7 @@
77#define MPTSCSIH_MAX_WIDTH 1 77#define MPTSCSIH_MAX_WIDTH 1
78#define MPTSCSIH_MIN_SYNC 0x08 78#define MPTSCSIH_MIN_SYNC 0x08
79#define MPTSCSIH_SAF_TE 0 79#define MPTSCSIH_SAF_TE 0
80#define MPTSCSIH_PT_CLEAR 0
80 81
81 82
82#endif 83#endif
@@ -105,3 +106,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
105extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 106extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
106extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 107extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
107extern void mptscsih_timer_expired(unsigned long data); 108extern void mptscsih_timer_expired(unsigned long data);
109extern void scsi_print_command(struct scsi_cmnd *cmd);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 587d1274fd74..5c0e307d1d5d 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
199 printk(MYIOC_s_WARN_FMT 199 printk(MYIOC_s_WARN_FMT
200 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 200 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
201 ioc->name, ioc); 201 ioc->name, ioc);
202 return -ENODEV; 202 return 0;
203 } 203 }
204 204
205 sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST)); 205 sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));