Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Adding in EEH support to the IBM FlashSystem 70/80 device driver

Changes in v2 include:
o Fixed spelling of guarantee.
o Fixed potential memory leak if slot reset fails out.
o Changed list_for_each_entry_safe with list_for_each_entry.

Signed-off-by: Philip J Kelleher <pjk1939@linux.vnet.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Philip J Kelleher and committed by
Jens Axboe
c95246c3 1ebfd109

+436 -67
+201 -2
drivers/block/rsxx/core.c
··· 30 30 #include <linux/reboot.h> 31 31 #include <linux/slab.h> 32 32 #include <linux/bitops.h> 33 + #include <linux/delay.h> 33 34 34 35 #include <linux/genhd.h> 35 36 #include <linux/idr.h> ··· 53 52 static DEFINE_SPINLOCK(rsxx_ida_lock); 54 53 55 54 /*----------------- Interrupt Control & Handling -------------------*/ 55 + 56 + static void rsxx_mask_interrupts(struct rsxx_cardinfo *card) 57 + { 58 + card->isr_mask = 0; 59 + card->ier_mask = 0; 60 + } 61 + 56 62 static void __enable_intr(unsigned int *mask, unsigned int intr) 57 63 { 58 64 *mask |= intr; ··· 79 71 */ 80 72 void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr) 81 73 { 82 - if (unlikely(card->halt)) 74 + if (unlikely(card->halt) || 75 + unlikely(card->eeh_state)) 83 76 return; 84 77 85 78 __enable_intr(&card->ier_mask, intr); ··· 89 80 90 81 void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr) 91 82 { 83 + if (unlikely(card->eeh_state)) 84 + return; 85 + 92 86 __disable_intr(&card->ier_mask, intr); 93 87 iowrite32(card->ier_mask, card->regmap + IER); 94 88 } ··· 99 87 void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card, 100 88 unsigned int intr) 101 89 { 102 - if (unlikely(card->halt)) 90 + if (unlikely(card->halt) || 91 + unlikely(card->eeh_state)) 103 92 return; 104 93 105 94 __enable_intr(&card->isr_mask, intr); ··· 110 97 void rsxx_disable_ier_and_isr(struct rsxx_cardinfo *card, 111 98 unsigned int intr) 112 99 { 100 + if (unlikely(card->eeh_state)) 101 + return; 102 + 113 103 __disable_intr(&card->isr_mask, intr); 114 104 __disable_intr(&card->ier_mask, intr); 115 105 iowrite32(card->ier_mask, card->regmap + IER); ··· 130 114 131 115 do { 132 116 reread_isr = 0; 117 + 118 + if (unlikely(card->eeh_state)) 119 + break; 133 120 134 121 isr = ioread32(card->regmap + ISR); 135 122 if (isr == 0xffffffff) { ··· 323 304 return 0; 324 305 } 325 306 307 + static void rsxx_eeh_frozen(struct pci_dev *dev) 308 + { 309 + struct rsxx_cardinfo *card = pci_get_drvdata(dev); 310 + int i; 311 + 312 + dev_warn(&dev->dev, "IBM FlashSystem PCI: preparing for slot reset.\n"); 313 + 314 + card->eeh_state = 1; 315 + rsxx_mask_interrupts(card); 316 + 317 + /* 318 + * We need to guarantee that the write for eeh_state and masking 319 + * interrupts does not become reordered. This will prevent a possible 320 + * race condition with the EEH code. 321 + */ 322 + wmb(); 323 + 324 + pci_disable_device(dev); 325 + 326 + rsxx_eeh_save_issued_dmas(card); 327 + 328 + rsxx_eeh_save_issued_creg(card); 329 + 330 + for (i = 0; i < card->n_targets; i++) { 331 + if (card->ctrl[i].status.buf) 332 + pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8, 333 + card->ctrl[i].status.buf, 334 + card->ctrl[i].status.dma_addr); 335 + if (card->ctrl[i].cmd.buf) 336 + pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8, 337 + card->ctrl[i].cmd.buf, 338 + card->ctrl[i].cmd.dma_addr); 339 + } 340 + } 341 + 342 + static void rsxx_eeh_failure(struct pci_dev *dev) 343 + { 344 + struct rsxx_cardinfo *card = pci_get_drvdata(dev); 345 + int i; 346 + 347 + dev_err(&dev->dev, "IBM FlashSystem PCI: disabling failed card.\n"); 348 + 349 + card->eeh_state = 1; 350 + 351 + for (i = 0; i < card->n_targets; i++) 352 + del_timer_sync(&card->ctrl[i].activity_timer); 353 + 354 + rsxx_eeh_cancel_dmas(card); 355 + } 356 + 357 + static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card) 358 + { 359 + unsigned int status; 360 + int iter = 0; 361 + 362 + /* We need to wait for the hardware to reset */ 363 + while (iter++ < 10) { 364 + status = ioread32(card->regmap + PCI_RECONFIG); 365 + 366 + if (status & RSXX_FLUSH_BUSY) { 367 + ssleep(1); 368 + continue; 369 + } 370 + 371 + if (status & RSXX_FLUSH_TIMEOUT) 372 + dev_warn(CARD_TO_DEV(card), "HW: flash controller timeout\n"); 373 + return 0; 374 + } 375 + 376 + /* Hardware failed resetting itself. */ 377 + return -1; 378 + } 379 + 380 + static pci_ers_result_t rsxx_error_detected(struct pci_dev *dev, 381 + enum pci_channel_state error) 382 + { 383 + if (dev->revision < RSXX_EEH_SUPPORT) 384 + return PCI_ERS_RESULT_NONE; 385 + 386 + if (error == pci_channel_io_perm_failure) { 387 + rsxx_eeh_failure(dev); 388 + return PCI_ERS_RESULT_DISCONNECT; 389 + } 390 + 391 + rsxx_eeh_frozen(dev); 392 + return PCI_ERS_RESULT_NEED_RESET; 393 + } 394 + 395 + static pci_ers_result_t rsxx_slot_reset(struct pci_dev *dev) 396 + { 397 + struct rsxx_cardinfo *card = pci_get_drvdata(dev); 398 + unsigned long flags; 399 + int i; 400 + int st; 401 + 402 + dev_warn(&dev->dev, 403 + "IBM FlashSystem PCI: recovering from slot reset.\n"); 404 + 405 + st = pci_enable_device(dev); 406 + if (st) 407 + goto failed_hw_setup; 408 + 409 + pci_set_master(dev); 410 + 411 + st = rsxx_eeh_fifo_flush_poll(card); 412 + if (st) 413 + goto failed_hw_setup; 414 + 415 + rsxx_dma_queue_reset(card); 416 + 417 + for (i = 0; i < card->n_targets; i++) { 418 + st = rsxx_hw_buffers_init(dev, &card->ctrl[i]); 419 + if (st) 420 + goto failed_hw_buffers_init; 421 + } 422 + 423 + if (card->config_valid) 424 + rsxx_dma_configure(card); 425 + 426 + /* Clears the ISR register from spurious interrupts */ 427 + st = ioread32(card->regmap + ISR); 428 + 429 + card->eeh_state = 0; 430 + 431 + st = rsxx_eeh_remap_dmas(card); 432 + if (st) 433 + goto failed_remap_dmas; 434 + 435 + spin_lock_irqsave(&card->irq_lock, flags); 436 + if (card->n_targets & RSXX_MAX_TARGETS) 437 + rsxx_enable_ier_and_isr(card, CR_INTR_ALL_G); 438 + else 439 + rsxx_enable_ier_and_isr(card, CR_INTR_ALL_C); 440 + spin_unlock_irqrestore(&card->irq_lock, flags); 441 + 442 + rsxx_kick_creg_queue(card); 443 + 444 + for (i = 0; i < card->n_targets; i++) { 445 + spin_lock(&card->ctrl[i].queue_lock); 446 + if (list_empty(&card->ctrl[i].queue)) { 447 + spin_unlock(&card->ctrl[i].queue_lock); 448 + continue; 449 + } 450 + spin_unlock(&card->ctrl[i].queue_lock); 451 + 452 + queue_work(card->ctrl[i].issue_wq, 453 + &card->ctrl[i].issue_dma_work); 454 + } 455 + 456 + dev_info(&dev->dev, "IBM FlashSystem PCI: recovery complete.\n"); 457 + 458 + return PCI_ERS_RESULT_RECOVERED; 459 + 460 + failed_hw_buffers_init: 461 + failed_remap_dmas: 462 + for (i = 0; i < card->n_targets; i++) { 463 + if (card->ctrl[i].status.buf) 464 + pci_free_consistent(card->dev, 465 + STATUS_BUFFER_SIZE8, 466 + card->ctrl[i].status.buf, 467 + card->ctrl[i].status.dma_addr); 468 + if (card->ctrl[i].cmd.buf) 469 + pci_free_consistent(card->dev, 470 + COMMAND_BUFFER_SIZE8, 471 + card->ctrl[i].cmd.buf, 472 + card->ctrl[i].cmd.dma_addr); 473 + } 474 + failed_hw_setup: 475 + rsxx_eeh_failure(dev); 476 + return PCI_ERS_RESULT_DISCONNECT; 477 + 478 + } 479 + 326 480 /*----------------- Driver Initialization & Setup -------------------*/ 327 481 /* Returns: 0 if the driver is compatible with the device 328 482 -1 if the driver is NOT compatible with the device */ ··· 575 383 576 384 spin_lock_init(&card->irq_lock); 577 385 card->halt = 0; 386 + card->eeh_state = 0; 578 387 579 388 spin_lock_irq(&card->irq_lock); 580 389 rsxx_disable_ier_and_isr(card, CR_INTR_ALL); ··· 786 593 card_shutdown(card); 787 594 } 788 595 596 + static const struct pci_error_handlers rsxx_err_handler = { 597 + .error_detected = rsxx_error_detected, 598 + .slot_reset = rsxx_slot_reset, 599 + }; 600 + 789 601 static DEFINE_PCI_DEVICE_TABLE(rsxx_pci_ids) = { 790 602 {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS70_FLASH)}, 791 603 {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS80_FLASH)}, ··· 806 608 .remove = rsxx_pci_remove, 807 609 .suspend = rsxx_pci_suspend, 808 610 .shutdown = rsxx_pci_shutdown, 611 + .err_handler = &rsxx_err_handler, 809 612 }; 810 613 811 614 static int __init rsxx_core_init(void)
+53 -6
drivers/block/rsxx/cregs.c
··· 58 58 #error Unknown endianess!!! Aborting... 59 59 #endif 60 60 61 - static void copy_to_creg_data(struct rsxx_cardinfo *card, 61 + static int copy_to_creg_data(struct rsxx_cardinfo *card, 62 62 int cnt8, 63 63 void *buf, 64 64 unsigned int stream) 65 65 { 66 66 int i = 0; 67 67 u32 *data = buf; 68 + 69 + if (unlikely(card->eeh_state)) 70 + return -EIO; 68 71 69 72 for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { 70 73 /* ··· 79 76 else 80 77 iowrite32(data[i], card->regmap + CREG_DATA(i)); 81 78 } 79 + 80 + return 0; 82 81 } 83 82 84 83 85 - static void copy_from_creg_data(struct rsxx_cardinfo *card, 84 + static int copy_from_creg_data(struct rsxx_cardinfo *card, 86 85 int cnt8, 87 86 void *buf, 88 87 unsigned int stream) 89 88 { 90 89 int i = 0; 91 90 u32 *data = buf; 91 + 92 + if (unlikely(card->eeh_state)) 93 + return -EIO; 92 94 93 95 for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { 94 96 /* ··· 105 97 else 106 98 data[i] = ioread32(card->regmap + CREG_DATA(i)); 107 99 } 100 + 101 + return 0; 108 102 } 109 103 110 104 static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) 111 105 { 106 + int st; 107 + 108 + if (unlikely(card->eeh_state)) 109 + return; 110 + 112 111 iowrite32(cmd->addr, card->regmap + CREG_ADD); 113 112 iowrite32(cmd->cnt8, card->regmap + CREG_CNT); 114 113 115 114 if (cmd->op == CREG_OP_WRITE) { 116 - if (cmd->buf) 117 - copy_to_creg_data(card, cmd->cnt8, 118 - cmd->buf, cmd->stream); 115 + if (cmd->buf) { 116 + st = copy_to_creg_data(card, cmd->cnt8, 117 + cmd->buf, cmd->stream); 118 + if (st) 119 + return; 120 + } 119 121 } 122 + 123 + if (unlikely(card->eeh_state)) 124 + return; 120 125 121 126 /* Setting the valid bit will kick off the command. */ 122 127 iowrite32(cmd->op, card->regmap + CREG_CMD); ··· 293 272 goto creg_done; 294 273 } 295 274 296 - copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); 275 + st = copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); 297 276 } 298 277 299 278 creg_done: ··· 694 673 } 695 674 696 675 return 0; 676 + } 677 + 678 + void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card) 679 + { 680 + struct creg_cmd *cmd = NULL; 681 + 682 + cmd = card->creg_ctrl.active_cmd; 683 + card->creg_ctrl.active_cmd = NULL; 684 + 685 + if (cmd) { 686 + del_timer_sync(&card->creg_ctrl.cmd_timer); 687 + 688 + spin_lock_bh(&card->creg_ctrl.lock); 689 + list_add(&cmd->list, &card->creg_ctrl.queue); 690 + card->creg_ctrl.q_depth++; 691 + card->creg_ctrl.active = 0; 692 + spin_unlock_bh(&card->creg_ctrl.lock); 693 + } 694 + } 695 + 696 + void rsxx_kick_creg_queue(struct rsxx_cardinfo *card) 697 + { 698 + spin_lock_bh(&card->creg_ctrl.lock); 699 + if (!list_empty(&card->creg_ctrl.queue)) 700 + creg_kick_queue(card); 701 + spin_unlock_bh(&card->creg_ctrl.lock); 697 702 } 698 703 699 704 /*------------ Initialization & Setup --------------*/
+158 -58
drivers/block/rsxx/dma.c
··· 81 81 HW_STATUS_FAULT = 0x08, 82 82 }; 83 83 84 - #define STATUS_BUFFER_SIZE8 4096 85 - #define COMMAND_BUFFER_SIZE8 4096 86 - 87 84 static struct kmem_cache *rsxx_dma_pool; 88 85 89 86 struct dma_tracker { ··· 119 122 return tgt; 120 123 } 121 124 122 - static void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) 125 + void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) 123 126 { 124 127 /* Reset all DMA Command/Status Queues */ 125 128 iowrite32(DMA_QUEUE_RESET, card->regmap + RESET); ··· 207 210 u32 q_depth = 0; 208 211 u32 intr_coal; 209 212 210 - if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE) 213 + if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE || 214 + unlikely(card->eeh_state)) 211 215 return; 212 216 213 217 for (i = 0; i < card->n_targets; i++) ··· 221 223 } 222 224 223 225 /*----------------- RSXX DMA Handling -------------------*/ 224 - static void rsxx_complete_dma(struct rsxx_cardinfo *card, 226 + static void rsxx_complete_dma(struct rsxx_dma_ctrl *ctrl, 225 227 struct rsxx_dma *dma, 226 228 unsigned int status) 227 229 { 228 230 if (status & DMA_SW_ERR) 229 - printk_ratelimited(KERN_ERR 230 - "SW Error in DMA(cmd x%02x, laddr x%08x)\n", 231 - dma->cmd, dma->laddr); 231 + ctrl->stats.dma_sw_err++; 232 232 if (status & DMA_HW_FAULT) 233 - printk_ratelimited(KERN_ERR 234 - "HW Fault in DMA(cmd x%02x, laddr x%08x)\n", 235 - dma->cmd, dma->laddr); 233 + ctrl->stats.dma_hw_fault++; 236 234 if (status & DMA_CANCELLED) 237 - printk_ratelimited(KERN_ERR 238 - "DMA Cancelled(cmd x%02x, laddr x%08x)\n", 239 - dma->cmd, dma->laddr); 235 + ctrl->stats.dma_cancelled++; 240 236 241 237 if (dma->dma_addr) 242 - pci_unmap_page(card->dev, dma->dma_addr, get_dma_size(dma), 238 + pci_unmap_page(ctrl->card->dev, dma->dma_addr, 239 + get_dma_size(dma), 243 240 dma->cmd == HW_CMD_BLK_WRITE ? 244 241 PCI_DMA_TODEVICE : 245 242 PCI_DMA_FROMDEVICE); 246 243 247 244 if (dma->cb) 248 - dma->cb(card, dma->cb_data, status ? 1 : 0); 245 + dma->cb(ctrl->card, dma->cb_data, status ? 1 : 0); 249 246 250 247 kmem_cache_free(rsxx_dma_pool, dma); 251 248 } ··· 323 330 if (requeue_cmd) 324 331 rsxx_requeue_dma(ctrl, dma); 325 332 else 326 - rsxx_complete_dma(ctrl->card, dma, status); 333 + rsxx_complete_dma(ctrl, dma, status); 327 334 } 328 335 329 336 static void dma_engine_stalled(unsigned long data) 330 337 { 331 338 struct rsxx_dma_ctrl *ctrl = (struct rsxx_dma_ctrl *)data; 332 339 333 - if (atomic_read(&ctrl->stats.hw_q_depth) == 0) 340 + if (atomic_read(&ctrl->stats.hw_q_depth) == 0 || 341 + unlikely(ctrl->card->eeh_state)) 334 342 return; 335 343 336 344 if (ctrl->cmd.idx != ioread32(ctrl->regmap + SW_CMD_IDX)) { ··· 363 369 ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work); 364 370 hw_cmd_buf = ctrl->cmd.buf; 365 371 366 - if (unlikely(ctrl->card->halt)) 372 + if (unlikely(ctrl->card->halt) || 373 + unlikely(ctrl->card->eeh_state)) 367 374 return; 368 375 369 376 while (1) { ··· 392 397 */ 393 398 if (unlikely(ctrl->card->dma_fault)) { 394 399 push_tracker(ctrl->trackers, tag); 395 - rsxx_complete_dma(ctrl->card, dma, DMA_CANCELLED); 400 + rsxx_complete_dma(ctrl, dma, DMA_CANCELLED); 396 401 continue; 397 402 } 398 403 ··· 430 435 atomic_add(cmds_pending, &ctrl->stats.hw_q_depth); 431 436 mod_timer(&ctrl->activity_timer, 432 437 jiffies + DMA_ACTIVITY_TIMEOUT); 438 + 439 + if (unlikely(ctrl->card->eeh_state)) { 440 + del_timer_sync(&ctrl->activity_timer); 441 + return; 442 + } 443 + 433 444 iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); 434 445 } 435 446 } ··· 454 453 hw_st_buf = ctrl->status.buf; 455 454 456 455 if (unlikely(ctrl->card->halt) || 457 - unlikely(ctrl->card->dma_fault)) 456 + unlikely(ctrl->card->dma_fault) || 457 + unlikely(ctrl->card->eeh_state)) 458 458 return; 459 459 460 460 count = le16_to_cpu(hw_st_buf[ctrl->status.idx].count); ··· 500 498 if (status) 501 499 rsxx_handle_dma_error(ctrl, dma, status); 502 500 else 503 - rsxx_complete_dma(ctrl->card, dma, 0); 501 + rsxx_complete_dma(ctrl, dma, 0); 504 502 505 503 push_tracker(ctrl->trackers, tag); 506 504 ··· 719 717 720 718 721 719 /*----------------- DMA Engine Initialization & Setup -------------------*/ 720 + int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) 721 + { 722 + ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, 723 + &ctrl->status.dma_addr); 724 + ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, 725 + &ctrl->cmd.dma_addr); 726 + if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) 727 + return -ENOMEM; 728 + 729 + memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); 730 + iowrite32(lower_32_bits(ctrl->status.dma_addr), 731 + ctrl->regmap + SB_ADD_LO); 732 + iowrite32(upper_32_bits(ctrl->status.dma_addr), 733 + ctrl->regmap + SB_ADD_HI); 734 + 735 + memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); 736 + iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); 737 + iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); 738 + 739 + ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); 740 + if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { 741 + dev_crit(&dev->dev, "Failed reading status cnt x%x\n", 742 + ctrl->status.idx); 743 + return -EINVAL; 744 + } 745 + iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); 746 + iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); 747 + 748 + ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); 749 + if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { 750 + dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", 751 + ctrl->status.idx); 752 + return -EINVAL; 753 + } 754 + iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); 755 + iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); 756 + 757 + return 0; 758 + } 759 + 722 760 static int rsxx_dma_ctrl_init(struct pci_dev *dev, 723 761 struct rsxx_dma_ctrl *ctrl) 724 762 { 725 763 int i; 764 + int st; 726 765 727 766 memset(&ctrl->stats, 0, sizeof(ctrl->stats)); 728 - 729 - ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, 730 - &ctrl->status.dma_addr); 731 - ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, 732 - &ctrl->cmd.dma_addr); 733 - if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) 734 - return -ENOMEM; 735 767 736 768 ctrl->trackers = vmalloc(DMA_TRACKER_LIST_SIZE8); 737 769 if (!ctrl->trackers) ··· 796 760 INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas); 797 761 INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done); 798 762 799 - memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); 800 - iowrite32(lower_32_bits(ctrl->status.dma_addr), 801 - ctrl->regmap + SB_ADD_LO); 802 - iowrite32(upper_32_bits(ctrl->status.dma_addr), 803 - ctrl->regmap + SB_ADD_HI); 804 - 805 - memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); 806 - iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); 807 - iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); 808 - 809 - ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); 810 - if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { 811 - dev_crit(&dev->dev, "Failed reading status cnt x%x\n", 812 - ctrl->status.idx); 813 - return -EINVAL; 814 - } 815 - iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); 816 - iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); 817 - 818 - ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); 819 - if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { 820 - dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", 821 - ctrl->status.idx); 822 - return -EINVAL; 823 - } 824 - iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); 825 - iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); 763 + st = rsxx_hw_buffers_init(dev, ctrl); 764 + if (st) 765 + return st; 826 766 827 767 return 0; 828 768 } ··· 834 822 return 0; 835 823 } 836 824 837 - static int rsxx_dma_configure(struct rsxx_cardinfo *card) 825 + int rsxx_dma_configure(struct rsxx_cardinfo *card) 838 826 { 839 827 u32 intr_coal; 840 828 ··· 980 968 } 981 969 } 982 970 971 + void rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) 972 + { 973 + int i; 974 + int j; 975 + int cnt; 976 + struct rsxx_dma *dma; 977 + struct list_head issued_dmas[card->n_targets]; 978 + 979 + for (i = 0; i < card->n_targets; i++) { 980 + INIT_LIST_HEAD(&issued_dmas[i]); 981 + cnt = 0; 982 + for (j = 0; j < RSXX_MAX_OUTSTANDING_CMDS; j++) { 983 + dma = get_tracker_dma(card->ctrl[i].trackers, j); 984 + if (dma == NULL) 985 + continue; 986 + 987 + if (dma->cmd == HW_CMD_BLK_WRITE) 988 + card->ctrl[i].stats.writes_issued--; 989 + else if (dma->cmd == HW_CMD_BLK_DISCARD) 990 + card->ctrl[i].stats.discards_issued--; 991 + else 992 + card->ctrl[i].stats.reads_issued--; 993 + 994 + list_add_tail(&dma->list, &issued_dmas[i]); 995 + push_tracker(card->ctrl[i].trackers, j); 996 + cnt++; 997 + } 998 + 999 + spin_lock(&card->ctrl[i].queue_lock); 1000 + list_splice(&issued_dmas[i], &card->ctrl[i].queue); 1001 + 1002 + atomic_sub(cnt, &card->ctrl[i].stats.hw_q_depth); 1003 + card->ctrl[i].stats.sw_q_depth += cnt; 1004 + card->ctrl[i].e_cnt = 0; 1005 + 1006 + list_for_each_entry(dma, &card->ctrl[i].queue, list) { 1007 + if (dma->dma_addr) 1008 + pci_unmap_page(card->dev, dma->dma_addr, 1009 + get_dma_size(dma), 1010 + dma->cmd == HW_CMD_BLK_WRITE ? 1011 + PCI_DMA_TODEVICE : 1012 + PCI_DMA_FROMDEVICE); 1013 + } 1014 + spin_unlock(&card->ctrl[i].queue_lock); 1015 + } 1016 + } 1017 + 1018 + void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card) 1019 + { 1020 + struct rsxx_dma *dma; 1021 + struct rsxx_dma *tmp; 1022 + int i; 1023 + 1024 + for (i = 0; i < card->n_targets; i++) { 1025 + spin_lock(&card->ctrl[i].queue_lock); 1026 + list_for_each_entry_safe(dma, tmp, &card->ctrl[i].queue, list) { 1027 + list_del(&dma->list); 1028 + 1029 + rsxx_complete_dma(&card->ctrl[i], dma, DMA_CANCELLED); 1030 + } 1031 + spin_unlock(&card->ctrl[i].queue_lock); 1032 + } 1033 + } 1034 + 1035 + int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card) 1036 + { 1037 + struct rsxx_dma *dma; 1038 + struct rsxx_dma *tmp; 1039 + int i; 1040 + 1041 + for (i = 0; i < card->n_targets; i++) { 1042 + spin_lock(&card->ctrl[i].queue_lock); 1043 + list_for_each_entry(dma, &card->ctrl[i].queue, list) { 1044 + dma->dma_addr = pci_map_page(card->dev, dma->page, 1045 + dma->pg_off, get_dma_size(dma), 1046 + dma->cmd == HW_CMD_BLK_WRITE ? 1047 + PCI_DMA_TODEVICE : 1048 + PCI_DMA_FROMDEVICE); 1049 + if (!dma->dma_addr) { 1050 + kmem_cache_free(rsxx_dma_pool, dma); 1051 + return -ENOMEM; 1052 + } 1053 + } 1054 + spin_unlock(&card->ctrl[i].queue_lock); 1055 + } 1056 + 1057 + return 0; 1058 + } 983 1059 984 1060 int rsxx_dma_init(void) 985 1061 {
+24 -1
drivers/block/rsxx/rsxx_priv.h
··· 64 64 #define RSXX_MAX_OUTSTANDING_CMDS 255 65 65 #define RSXX_CS_IDX_MASK 0xff 66 66 67 + #define STATUS_BUFFER_SIZE8 4096 68 + #define COMMAND_BUFFER_SIZE8 4096 69 + 67 70 #define RSXX_MAX_TARGETS 8 68 71 69 72 struct dma_tracker_list; ··· 91 88 u32 discards_failed; 92 89 u32 done_rescheduled; 93 90 u32 issue_rescheduled; 91 + u32 dma_sw_err; 92 + u32 dma_hw_fault; 93 + u32 dma_cancelled; 94 94 u32 sw_q_depth; /* Number of DMAs on the SW queue. */ 95 95 atomic_t hw_q_depth; /* Number of DMAs queued to HW. */ 96 96 }; ··· 119 113 struct rsxx_cardinfo { 120 114 struct pci_dev *dev; 121 115 unsigned int halt; 116 + unsigned int eeh_state; 122 117 123 118 void __iomem *regmap; 124 119 spinlock_t irq_lock; ··· 228 221 PERF_RD512_HI = 0xac, 229 222 PERF_WR512_LO = 0xb0, 230 223 PERF_WR512_HI = 0xb4, 224 + PCI_RECONFIG = 0xb8, 231 225 }; 232 226 233 227 enum rsxx_intr { ··· 242 234 CR_INTR_DMA5 = 0x00000080, 243 235 CR_INTR_DMA6 = 0x00000100, 244 236 CR_INTR_DMA7 = 0x00000200, 237 + CR_INTR_ALL_C = 0x0000003f, 238 + CR_INTR_ALL_G = 0x000003ff, 245 239 CR_INTR_DMA_ALL = 0x000003f5, 246 240 CR_INTR_ALL = 0xffffffff, 247 241 }; ··· 260 250 DMA_QUEUE_RESET = 0x00000001, 261 251 }; 262 252 253 + enum rsxx_hw_fifo_flush { 254 + RSXX_FLUSH_BUSY = 0x00000002, 255 + RSXX_FLUSH_TIMEOUT = 0x00000004, 256 + }; 257 + 263 258 enum rsxx_pci_revision { 264 259 RSXX_DISCARD_SUPPORT = 2, 260 + RSXX_EEH_SUPPORT = 3, 265 261 }; 266 262 267 263 enum rsxx_creg_cmd { ··· 373 357 void rsxx_dma_destroy(struct rsxx_cardinfo *card); 374 358 int rsxx_dma_init(void); 375 359 void rsxx_dma_cleanup(void); 360 + void rsxx_dma_queue_reset(struct rsxx_cardinfo *card); 361 + int rsxx_dma_configure(struct rsxx_cardinfo *card); 376 362 int rsxx_dma_queue_bio(struct rsxx_cardinfo *card, 377 363 struct bio *bio, 378 364 atomic_t *n_dmas, 379 365 rsxx_dma_cb cb, 380 366 void *cb_data); 367 + int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl); 368 + void rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card); 369 + void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card); 370 + int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card); 381 371 382 372 /***** cregs.c *****/ 383 373 int rsxx_creg_write(struct rsxx_cardinfo *card, u32 addr, ··· 408 386 void rsxx_creg_destroy(struct rsxx_cardinfo *card); 409 387 int rsxx_creg_init(void); 410 388 void rsxx_creg_cleanup(void); 411 - 412 389 int rsxx_reg_access(struct rsxx_cardinfo *card, 413 390 struct rsxx_reg_access __user *ucmd, 414 391 int read); 392 + void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card); 393 + void rsxx_kick_creg_queue(struct rsxx_cardinfo *card); 415 394 416 395 417 396