aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
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 /drivers/message/fusion/mptbase.c
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>
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r--drivers/message/fusion/mptbase.c449
1 files changed, 282 insertions, 167 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.