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. |
