aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/cciss.c98
-rw-r--r--drivers/block/cciss.h9
2 files changed, 3 insertions, 104 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 9a9db6deefcd..b22cec97ea19 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2612,51 +2612,6 @@ static unsigned long pollcomplete(int ctlr)
2612 return 1; 2612 return 1;
2613} 2613}
2614 2614
2615static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete)
2616{
2617 /* We get in here if sendcmd() is polling for completions
2618 and gets some command back that it wasn't expecting --
2619 something other than that which it just sent down.
2620 Ordinarily, that shouldn't happen, but it can happen when
2621 the scsi tape stuff gets into error handling mode, and
2622 starts using sendcmd() to try to abort commands and
2623 reset tape drives. In that case, sendcmd may pick up
2624 completions of commands that were sent to logical drives
2625 through the block i/o system, or cciss ioctls completing, etc.
2626 In that case, we need to save those completions for later
2627 processing by the interrupt handler.
2628 */
2629
2630#ifdef CONFIG_CISS_SCSI_TAPE
2631 struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects;
2632
2633 /* If it's not the scsi tape stuff doing error handling, (abort */
2634 /* or reset) then we don't expect anything weird. */
2635 if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) {
2636#endif
2637 printk(KERN_WARNING "cciss cciss%d: SendCmd "
2638 "Invalid command list address returned! (%lx)\n",
2639 ctlr, complete);
2640 /* not much we can do. */
2641#ifdef CONFIG_CISS_SCSI_TAPE
2642 return 1;
2643 }
2644
2645 /* We've sent down an abort or reset, but something else
2646 has completed */
2647 if (srl->ncompletions >= (hba[ctlr]->nr_cmds + 2)) {
2648 /* Uh oh. No room to save it for later... */
2649 printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, "
2650 "reject list overflow, command lost!\n", ctlr);
2651 return 1;
2652 }
2653 /* Save it for later */
2654 srl->complete[srl->ncompletions] = complete;
2655 srl->ncompletions++;
2656#endif
2657 return 0;
2658}
2659
2660/* Send command c to controller h and poll for it to complete. 2615/* Send command c to controller h and poll for it to complete.
2661 * Turns interrupts off on the board. Used at driver init time 2616 * Turns interrupts off on the board. Used at driver init time
2662 * and during SCSI error recovery. 2617 * and during SCSI error recovery.
@@ -2701,11 +2656,10 @@ resend_cmd1:
2701 break; 2656 break;
2702 } 2657 }
2703 2658
2704 /* If it's not the cmd we're looking for, save it for later */ 2659 /* Make sure it's the command we're expecting. */
2705 if ((complete & ~CISS_ERROR_BIT) != c->busaddr) { 2660 if ((complete & ~CISS_ERROR_BIT) != c->busaddr) {
2706 if (add_sendcmd_reject(c->Request.CDB[0], 2661 printk(KERN_WARNING "cciss%d: Unexpected command "
2707 h->ctlr, complete) != 0) 2662 "completion.\n", h->ctlr);
2708 BUG(); /* we are hosed if we get here. */
2709 continue; 2663 continue;
2710 } 2664 }
2711 2665
@@ -2770,11 +2724,6 @@ resend_cmd1:
2770 buff_dma_handle.val32.upper = c->SG[0].Addr.upper; 2724 buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
2771 pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val, 2725 pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val,
2772 c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); 2726 c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
2773#ifdef CONFIG_CISS_SCSI_TAPE
2774 /* if we saved some commands for later, process them now. */
2775 if (h->scsi_rejects.ncompletions > 0)
2776 do_cciss_intr(0, h);
2777#endif
2778 return status; 2727 return status;
2779} 2728}
2780 2729
@@ -3195,44 +3144,18 @@ startio:
3195 3144
3196static inline unsigned long get_next_completion(ctlr_info_t *h) 3145static inline unsigned long get_next_completion(ctlr_info_t *h)
3197{ 3146{
3198#ifdef CONFIG_CISS_SCSI_TAPE
3199 /* Any rejects from sendcmd() lying around? Process them first */
3200 if (h->scsi_rejects.ncompletions == 0)
3201 return h->access.command_completed(h);
3202 else {
3203 struct sendcmd_reject_list *srl;
3204 int n;
3205 srl = &h->scsi_rejects;
3206 n = --srl->ncompletions;
3207 /* printk("cciss%d: processing saved reject\n", h->ctlr); */
3208 printk("p");
3209 return srl->complete[n];
3210 }
3211#else
3212 return h->access.command_completed(h); 3147 return h->access.command_completed(h);
3213#endif
3214} 3148}
3215 3149
3216static inline int interrupt_pending(ctlr_info_t *h) 3150static inline int interrupt_pending(ctlr_info_t *h)
3217{ 3151{
3218#ifdef CONFIG_CISS_SCSI_TAPE
3219 return (h->access.intr_pending(h)
3220 || (h->scsi_rejects.ncompletions > 0));
3221#else
3222 return h->access.intr_pending(h); 3152 return h->access.intr_pending(h);
3223#endif
3224} 3153}
3225 3154
3226static inline long interrupt_not_for_us(ctlr_info_t *h) 3155static inline long interrupt_not_for_us(ctlr_info_t *h)
3227{ 3156{
3228#ifdef CONFIG_CISS_SCSI_TAPE
3229 return (((h->access.intr_pending(h) == 0) ||
3230 (h->interrupts_enabled == 0))
3231 && (h->scsi_rejects.ncompletions == 0));
3232#else
3233 return (((h->access.intr_pending(h) == 0) || 3157 return (((h->access.intr_pending(h) == 0) ||
3234 (h->interrupts_enabled == 0))); 3158 (h->interrupts_enabled == 0)));
3235#endif
3236} 3159}
3237 3160
3238static irqreturn_t do_cciss_intr(int irq, void *dev_id) 3161static irqreturn_t do_cciss_intr(int irq, void *dev_id)
@@ -4054,15 +3977,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4054 printk(KERN_ERR "cciss: out of memory"); 3977 printk(KERN_ERR "cciss: out of memory");
4055 goto clean4; 3978 goto clean4;
4056 } 3979 }
4057#ifdef CONFIG_CISS_SCSI_TAPE
4058 hba[i]->scsi_rejects.complete =
4059 kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) *
4060 (hba[i]->nr_cmds + 5), GFP_KERNEL);
4061 if (hba[i]->scsi_rejects.complete == NULL) {
4062 printk(KERN_ERR "cciss: out of memory");
4063 goto clean4;
4064 }
4065#endif
4066 spin_lock_init(&hba[i]->lock); 3980 spin_lock_init(&hba[i]->lock);
4067 3981
4068 /* Initialize the pdev driver private data. 3982 /* Initialize the pdev driver private data.
@@ -4122,9 +4036,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4122 4036
4123clean4: 4037clean4:
4124 kfree(inq_buff); 4038 kfree(inq_buff);
4125#ifdef CONFIG_CISS_SCSI_TAPE
4126 kfree(hba[i]->scsi_rejects.complete);
4127#endif
4128 kfree(hba[i]->cmd_pool_bits); 4039 kfree(hba[i]->cmd_pool_bits);
4129 if (hba[i]->cmd_pool) 4040 if (hba[i]->cmd_pool)
4130 pci_free_consistent(hba[i]->pdev, 4041 pci_free_consistent(hba[i]->pdev,
@@ -4242,9 +4153,6 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
4242 pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct), 4153 pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
4243 hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); 4154 hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
4244 kfree(hba[i]->cmd_pool_bits); 4155 kfree(hba[i]->cmd_pool_bits);
4245#ifdef CONFIG_CISS_SCSI_TAPE
4246 kfree(hba[i]->scsi_rejects.complete);
4247#endif
4248 /* 4156 /*
4249 * Deliberately omit pci_disable_device(): it does something nasty to 4157 * Deliberately omit pci_disable_device(): it does something nasty to
4250 * Smart Array controllers that pci_enable_device does not undo 4158 * Smart Array controllers that pci_enable_device does not undo
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 25cd58e25021..06a5db25b298 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -53,14 +53,6 @@ typedef struct _drive_info_struct
53 char rev[REV_LEN + 1]; /* SCSI revision string */ 53 char rev[REV_LEN + 1]; /* SCSI revision string */
54} drive_info_struct; 54} drive_info_struct;
55 55
56#ifdef CONFIG_CISS_SCSI_TAPE
57
58struct sendcmd_reject_list {
59 int ncompletions;
60 unsigned long *complete; /* array of NR_CMDS tags */
61};
62
63#endif
64struct ctlr_info 56struct ctlr_info
65{ 57{
66 int ctlr; 58 int ctlr;
@@ -128,7 +120,6 @@ struct ctlr_info
128 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ 120 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
129 /* list of block side commands the scsi error handling sucked up */ 121 /* list of block side commands the scsi error handling sucked up */
130 /* and saved for later processing */ 122 /* and saved for later processing */
131 struct sendcmd_reject_list scsi_rejects;
132#endif 123#endif
133 unsigned char alive; 124 unsigned char alive;
134 struct completion *rescan_wait; 125 struct completion *rescan_wait;