aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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));