aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
diff options
context:
space:
mode:
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.