diff options
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 449 |
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 | ||
136 | static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); | 136 | static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); |
137 | static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); | 137 | static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); |
138 | //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); | ||
139 | static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); | 138 | static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); |
140 | static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); | 139 | static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); |
141 | static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); | 140 | static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); |
@@ -178,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t * | |||
178 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | 177 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); |
179 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); | 178 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); |
180 | static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); | 179 | static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); |
180 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); | ||
181 | 181 | ||
182 | /* module entry point */ | 182 | /* module entry point */ |
183 | static int __init fusion_init (void); | 183 | static 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 | */ | ||
215 | static void | ||
216 | mpt_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 | |||
276 | static void | ||
277 | mpt_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) | |||
230 | static irqreturn_t | 368 | static irqreturn_t |
231 | mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) | 369 | mpt_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 | */ | ||
6093 | static void | ||
6094 | mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) | ||
6095 | { | ||
6096 | union 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. |