aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c72
1 files changed, 62 insertions, 10 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 7dc7810b7482..c422220db0ae 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -151,18 +151,22 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba)
151} 151}
152 152
153struct lpfc_scsi_buf* 153struct lpfc_scsi_buf*
154lpfc_sli_get_scsi_buf(struct lpfc_hba * phba) 154lpfc_get_scsi_buf(struct lpfc_hba * phba)
155{ 155{
156 struct lpfc_scsi_buf * lpfc_cmd = NULL; 156 struct lpfc_scsi_buf * lpfc_cmd = NULL;
157 struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; 157 struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
158 unsigned long iflag = 0;
158 159
160 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
159 list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); 161 list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
162 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
160 return lpfc_cmd; 163 return lpfc_cmd;
161} 164}
162 165
163static void 166static void
164lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) 167lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
165{ 168{
169 unsigned long iflag = 0;
166 /* 170 /*
167 * There are only two special cases to consider. (1) the scsi command 171 * There are only two special cases to consider. (1) the scsi command
168 * requested scatter-gather usage or (2) the scsi command allocated 172 * requested scatter-gather usage or (2) the scsi command allocated
@@ -180,8 +184,10 @@ lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
180 } 184 }
181 } 185 }
182 186
187 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
183 psb->pCmd = NULL; 188 psb->pCmd = NULL;
184 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); 189 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
190 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
185} 191}
186 192
187static int 193static int
@@ -403,7 +409,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
403 struct lpfc_rport_data *rdata = lpfc_cmd->rdata; 409 struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
404 struct lpfc_nodelist *pnode = rdata->pnode; 410 struct lpfc_nodelist *pnode = rdata->pnode;
405 struct scsi_cmnd *cmd = lpfc_cmd->pCmd; 411 struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
406 unsigned long iflag;
407 412
408 lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; 413 lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
409 lpfc_cmd->status = pIocbOut->iocb.ulpStatus; 414 lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@@ -457,9 +462,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
457 462
458 cmd->scsi_done(cmd); 463 cmd->scsi_done(cmd);
459 464
460 spin_lock_irqsave(phba->host->host_lock, iflag);
461 lpfc_release_scsi_buf(phba, lpfc_cmd); 465 lpfc_release_scsi_buf(phba, lpfc_cmd);
462 spin_unlock_irqrestore(phba->host->host_lock, iflag);
463} 466}
464 467
465static void 468static void
@@ -707,6 +710,37 @@ lpfc_info(struct Scsi_Host *host)
707 return lpfcinfobuf; 710 return lpfcinfobuf;
708} 711}
709 712
713static __inline__ void lpfc_poll_rearm_timer(struct lpfc_hba * phba)
714{
715 unsigned long poll_tmo_expires =
716 (jiffies + msecs_to_jiffies(phba->cfg_poll_tmo));
717
718 if (phba->sli.ring[LPFC_FCP_RING].txcmplq_cnt)
719 mod_timer(&phba->fcp_poll_timer,
720 poll_tmo_expires);
721}
722
723void lpfc_poll_start_timer(struct lpfc_hba * phba)
724{
725 lpfc_poll_rearm_timer(phba);
726}
727
728void lpfc_poll_timeout(unsigned long ptr)
729{
730 struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
731 unsigned long iflag;
732
733 spin_lock_irqsave(phba->host->host_lock, iflag);
734
735 if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
736 lpfc_sli_poll_fcp_ring (phba);
737 if (phba->cfg_poll & DISABLE_FCP_RING_INT)
738 lpfc_poll_rearm_timer(phba);
739 }
740
741 spin_unlock_irqrestore(phba->host->host_lock, iflag);
742}
743
710static int 744static int
711lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) 745lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
712{ 746{
@@ -733,7 +767,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
733 cmnd->result = ScsiResult(DID_BUS_BUSY, 0); 767 cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
734 goto out_fail_command; 768 goto out_fail_command;
735 } 769 }
736 lpfc_cmd = lpfc_sli_get_scsi_buf (phba); 770 lpfc_cmd = lpfc_get_scsi_buf (phba);
737 if (lpfc_cmd == NULL) { 771 if (lpfc_cmd == NULL) {
738 lpfc_printf_log(phba, KERN_INFO, LOG_FCP, 772 lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
739 "%d:0707 driver's buffer pool is empty, " 773 "%d:0707 driver's buffer pool is empty, "
@@ -761,11 +795,17 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
761 &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); 795 &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
762 if (err) 796 if (err)
763 goto out_host_busy_free_buf; 797 goto out_host_busy_free_buf;
798
799 if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
800 lpfc_sli_poll_fcp_ring(phba);
801 if (phba->cfg_poll & DISABLE_FCP_RING_INT)
802 lpfc_poll_rearm_timer(phba);
803 }
804
764 return 0; 805 return 0;
765 806
766 out_host_busy_free_buf: 807 out_host_busy_free_buf:
767 lpfc_release_scsi_buf(phba, lpfc_cmd); 808 lpfc_release_scsi_buf(phba, lpfc_cmd);
768 cmnd->host_scribble = NULL;
769 out_host_busy: 809 out_host_busy:
770 return SCSI_MLQUEUE_HOST_BUSY; 810 return SCSI_MLQUEUE_HOST_BUSY;
771 811
@@ -839,9 +879,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
839 goto out; 879 goto out;
840 } 880 }
841 881
882 if (phba->cfg_poll & DISABLE_FCP_RING_INT)
883 lpfc_sli_poll_fcp_ring (phba);
884
842 /* Wait for abort to complete */ 885 /* Wait for abort to complete */
843 while (lpfc_cmd->pCmd == cmnd) 886 while (lpfc_cmd->pCmd == cmnd)
844 { 887 {
888 if (phba->cfg_poll & DISABLE_FCP_RING_INT)
889 lpfc_sli_poll_fcp_ring (phba);
890
845 spin_unlock_irq(phba->host->host_lock); 891 spin_unlock_irq(phba->host->host_lock);
846 schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ); 892 schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
847 spin_lock_irq(phba->host->host_lock); 893 spin_lock_irq(phba->host->host_lock);
@@ -905,7 +951,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
905 break; 951 break;
906 } 952 }
907 953
908 lpfc_cmd = lpfc_sli_get_scsi_buf (phba); 954 lpfc_cmd = lpfc_get_scsi_buf (phba);
909 if (lpfc_cmd == NULL) 955 if (lpfc_cmd == NULL)
910 goto out; 956 goto out;
911 957
@@ -1001,7 +1047,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1001 lpfc_block_requests(phba); 1047 lpfc_block_requests(phba);
1002 spin_lock_irq(shost->host_lock); 1048 spin_lock_irq(shost->host_lock);
1003 1049
1004 lpfc_cmd = lpfc_sli_get_scsi_buf (phba); 1050 lpfc_cmd = lpfc_get_scsi_buf(phba);
1005 if (lpfc_cmd == NULL) 1051 if (lpfc_cmd == NULL)
1006 goto out; 1052 goto out;
1007 1053
@@ -1136,10 +1182,10 @@ lpfc_slave_alloc(struct scsi_device *sdev)
1136 break; 1182 break;
1137 } 1183 }
1138 1184
1139 spin_lock_irqsave(phba->host->host_lock, flags); 1185 spin_lock_irqsave(&phba->scsi_buf_list_lock, flags);
1140 phba->total_scsi_bufs++; 1186 phba->total_scsi_bufs++;
1141 list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list); 1187 list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list);
1142 spin_unlock_irqrestore(phba->host->host_lock, flags); 1188 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, flags);
1143 } 1189 }
1144 return 0; 1190 return 0;
1145} 1191}
@@ -1163,6 +1209,12 @@ lpfc_slave_configure(struct scsi_device *sdev)
1163 */ 1209 */
1164 rport->dev_loss_tmo = phba->cfg_nodev_tmo + 5; 1210 rport->dev_loss_tmo = phba->cfg_nodev_tmo + 5;
1165 1211
1212 if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
1213 lpfc_sli_poll_fcp_ring(phba);
1214 if (phba->cfg_poll & DISABLE_FCP_RING_INT)
1215 lpfc_poll_rearm_timer(phba);
1216 }
1217
1166 return 0; 1218 return 0;
1167} 1219}
1168 1220