diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 92 |
1 files changed, 34 insertions, 58 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 7a8b3b90af71..3759ae1dc5e7 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -57,45 +57,27 @@ | |||
57 | 57 | ||
58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; | 58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; |
59 | 59 | ||
60 | /* | ||
61 | * lpfc_ct_unsol_event | ||
62 | */ | ||
63 | static void | 60 | static void |
64 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 61 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
65 | struct lpfc_dmabuf *mp, uint32_t size) | 62 | struct lpfc_dmabuf *mp, uint32_t size) |
66 | { | 63 | { |
67 | if (!mp) { | 64 | if (!mp) { |
68 | printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, " | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
69 | "piocbq = %p, status = x%x, mp = %p, size = %d\n", | 66 | "0146 Ignoring unsolicted CT No HBQ " |
70 | __FUNCTION__, __LINE__, | 67 | "status = x%x\n", |
71 | piocbq, piocbq->iocb.ulpStatus, mp, size); | 68 | piocbq->iocb.ulpStatus); |
72 | } | 69 | } |
73 | 70 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | |
74 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, " | 71 | "0145 Ignoring unsolicted CT HBQ Size:%d " |
75 | "buffer = %p, size = %d, status = x%x\n", | 72 | "status = x%x\n", |
76 | __FUNCTION__, __LINE__, | 73 | size, piocbq->iocb.ulpStatus); |
77 | piocbq, mp, size, | ||
78 | piocbq->iocb.ulpStatus); | ||
79 | |||
80 | } | 74 | } |
81 | 75 | ||
82 | static void | 76 | static void |
83 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 77 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
84 | struct lpfc_dmabuf *mp, uint32_t size) | 78 | struct lpfc_dmabuf *mp, uint32_t size) |
85 | { | 79 | { |
86 | if (!mp) { | 80 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size); |
87 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
88 | "HBQ buffer, piocbq = %p, status = x%x\n", | ||
89 | __FUNCTION__, __LINE__, | ||
90 | piocbq, piocbq->iocb.ulpStatus); | ||
91 | } else { | ||
92 | lpfc_ct_unsol_buffer(phba, piocbq, mp, size); | ||
93 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT " | ||
94 | "piocbq = %p, buffer = %p, size = %d, " | ||
95 | "status = x%x\n", | ||
96 | __FUNCTION__, __LINE__, | ||
97 | piocbq, mp, size, piocbq->iocb.ulpStatus); | ||
98 | } | ||
99 | } | 81 | } |
100 | 82 | ||
101 | void | 83 | void |
@@ -109,11 +91,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
109 | struct lpfc_iocbq *iocbq; | 91 | struct lpfc_iocbq *iocbq; |
110 | dma_addr_t paddr; | 92 | dma_addr_t paddr; |
111 | uint32_t size; | 93 | uint32_t size; |
112 | struct lpfc_dmabuf *bdeBuf1 = piocbq->context2; | 94 | struct list_head head; |
113 | struct lpfc_dmabuf *bdeBuf2 = piocbq->context3; | 95 | struct lpfc_dmabuf *bdeBuf; |
114 | |||
115 | piocbq->context2 = NULL; | ||
116 | piocbq->context3 = NULL; | ||
117 | 96 | ||
118 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { | 97 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { |
119 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | 98 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); |
@@ -122,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
122 | /* Not enough posted buffers; Try posting more buffers */ | 101 | /* Not enough posted buffers; Try posting more buffers */ |
123 | phba->fc_stat.NoRcvBuf++; | 102 | phba->fc_stat.NoRcvBuf++; |
124 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) | 103 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) |
125 | lpfc_post_buffer(phba, pring, 0, 1); | 104 | lpfc_post_buffer(phba, pring, 2, 1); |
126 | return; | 105 | return; |
127 | } | 106 | } |
128 | 107 | ||
@@ -133,38 +112,34 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
133 | return; | 112 | return; |
134 | 113 | ||
135 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 114 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
136 | list_for_each_entry(iocbq, &piocbq->list, list) { | 115 | INIT_LIST_HEAD(&head); |
116 | list_add_tail(&head, &piocbq->list); | ||
117 | list_for_each_entry(iocbq, &head, list) { | ||
137 | icmd = &iocbq->iocb; | 118 | icmd = &iocbq->iocb; |
138 | if (icmd->ulpBdeCount == 0) { | 119 | if (icmd->ulpBdeCount == 0) |
139 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
140 | "BDE, iocbq = %p, status = x%x\n", | ||
141 | __FUNCTION__, __LINE__, | ||
142 | iocbq, iocbq->iocb.ulpStatus); | ||
143 | continue; | 120 | continue; |
144 | } | 121 | bdeBuf = iocbq->context2; |
145 | 122 | iocbq->context2 = NULL; | |
146 | size = icmd->un.cont64[0].tus.f.bdeSize; | 123 | size = icmd->un.cont64[0].tus.f.bdeSize; |
147 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size); | 124 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); |
148 | lpfc_in_buf_free(phba, bdeBuf1); | 125 | lpfc_in_buf_free(phba, bdeBuf); |
149 | if (icmd->ulpBdeCount == 2) { | 126 | if (icmd->ulpBdeCount == 2) { |
150 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2, | 127 | bdeBuf = iocbq->context3; |
151 | size); | 128 | iocbq->context3 = NULL; |
152 | lpfc_in_buf_free(phba, bdeBuf2); | 129 | size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize; |
130 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, | ||
131 | size); | ||
132 | lpfc_in_buf_free(phba, bdeBuf); | ||
153 | } | 133 | } |
154 | } | 134 | } |
135 | list_del(&head); | ||
155 | } else { | 136 | } else { |
156 | struct lpfc_iocbq *next; | 137 | struct lpfc_iocbq *next; |
157 | 138 | ||
158 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { | 139 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { |
159 | icmd = &iocbq->iocb; | 140 | icmd = &iocbq->iocb; |
160 | if (icmd->ulpBdeCount == 0) { | 141 | if (icmd->ulpBdeCount == 0) |
161 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | 142 | lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0); |
162 | "BDE, iocbq = %p, status = x%x\n", | ||
163 | __FUNCTION__, __LINE__, | ||
164 | iocbq, iocbq->iocb.ulpStatus); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | for (i = 0; i < icmd->ulpBdeCount; i++) { | 143 | for (i = 0; i < icmd->ulpBdeCount; i++) { |
169 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, | 144 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, |
170 | icmd->un.cont64[i].addrLow); | 145 | icmd->un.cont64[i].addrLow); |
@@ -176,6 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
176 | } | 151 | } |
177 | list_del(&iocbq->list); | 152 | list_del(&iocbq->list); |
178 | lpfc_sli_release_iocbq(phba, iocbq); | 153 | lpfc_sli_release_iocbq(phba, iocbq); |
154 | lpfc_post_buffer(phba, pring, i, 1); | ||
179 | } | 155 | } |
180 | } | 156 | } |
181 | } | 157 | } |