aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-12-04 22:39:40 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:27 -0500
commit9f1e1b50ab43a281dbc75c25f11e1926a9ea367a (patch)
treea88f66e6205bd1dbff333b1a9da9fb62cd6f0cd5 /drivers/scsi/lpfc/lpfc_sli.c
parent5b75da2fa2c9570c3c3dbb2f63cae5b4183e0ca3 (diff)
[SCSI] lpfc 8.3.0 : Fix some memory handling issues
- Fix mailbox buffer leak on dump mailbox completion - Fix mbuf leak in lpfc_pci_probe_one() SLI-2 mode error path - Don't allocate HBQs in interrupt context - Use correct size for FCP response buffer so that all available sense data is copied - Fix jiffies calculation to prevent crash when collecting statistical data Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c76
1 files changed, 8 insertions, 68 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 4e5b4ee121f1..632feee233ca 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1259,68 +1259,6 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
1259} 1259}
1260 1260
1261/** 1261/**
1262 * lpfc_sli_replace_hbqbuff: Replace the HBQ buffer with a new buffer.
1263 * @phba: Pointer to HBA context object.
1264 * @tag: Tag for the HBQ buffer.
1265 *
1266 * This function is called from unsolicited event handler code path to get the
1267 * HBQ buffer associated with an unsolicited iocb. This function is called with
1268 * no lock held. It returns the buffer associated with the given tag and posts
1269 * another buffer to the firmware. Note that the new buffer must be allocated
1270 * before taking the hbalock and that the hba lock must be held until it is
1271 * finished with the hbq entry swap.
1272 **/
1273static struct lpfc_dmabuf *
1274lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
1275{
1276 struct hbq_dmabuf *hbq_entry, *new_hbq_entry;
1277 uint32_t hbqno;
1278 void *virt; /* virtual address ptr */
1279 dma_addr_t phys; /* mapped address */
1280 unsigned long flags;
1281
1282 hbqno = tag >> 16;
1283 new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
1284 /* Check whether HBQ is still in use */
1285 spin_lock_irqsave(&phba->hbalock, flags);
1286 if (!phba->hbq_in_use) {
1287 if (new_hbq_entry)
1288 (phba->hbqs[hbqno].hbq_free_buffer)(phba,
1289 new_hbq_entry);
1290 spin_unlock_irqrestore(&phba->hbalock, flags);
1291 return NULL;
1292 }
1293
1294 hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
1295 if (hbq_entry == NULL) {
1296 if (new_hbq_entry)
1297 (phba->hbqs[hbqno].hbq_free_buffer)(phba,
1298 new_hbq_entry);
1299 spin_unlock_irqrestore(&phba->hbalock, flags);
1300 return NULL;
1301 }
1302 list_del(&hbq_entry->dbuf.list);
1303
1304 if (new_hbq_entry == NULL) {
1305 list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
1306 spin_unlock_irqrestore(&phba->hbalock, flags);
1307 return &hbq_entry->dbuf;
1308 }
1309 new_hbq_entry->tag = -1;
1310 phys = new_hbq_entry->dbuf.phys;
1311 virt = new_hbq_entry->dbuf.virt;
1312 new_hbq_entry->dbuf.phys = hbq_entry->dbuf.phys;
1313 new_hbq_entry->dbuf.virt = hbq_entry->dbuf.virt;
1314 hbq_entry->dbuf.phys = phys;
1315 hbq_entry->dbuf.virt = virt;
1316 lpfc_sli_free_hbq(phba, hbq_entry);
1317 list_add_tail(&new_hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
1318 spin_unlock_irqrestore(&phba->hbalock, flags);
1319
1320 return &new_hbq_entry->dbuf;
1321}
1322
1323/**
1324 * lpfc_sli_get_buff: Get the buffer associated with the buffer tag. 1262 * lpfc_sli_get_buff: Get the buffer associated with the buffer tag.
1325 * @phba: Pointer to HBA context object. 1263 * @phba: Pointer to HBA context object.
1326 * @pring: Pointer to driver SLI ring object. 1264 * @pring: Pointer to driver SLI ring object.
@@ -1334,13 +1272,17 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
1334 **/ 1272 **/
1335static struct lpfc_dmabuf * 1273static struct lpfc_dmabuf *
1336lpfc_sli_get_buff(struct lpfc_hba *phba, 1274lpfc_sli_get_buff(struct lpfc_hba *phba,
1337 struct lpfc_sli_ring *pring, 1275 struct lpfc_sli_ring *pring,
1338 uint32_t tag) 1276 uint32_t tag)
1339{ 1277{
1278 struct hbq_dmabuf *hbq_entry;
1279
1340 if (tag & QUE_BUFTAG_BIT) 1280 if (tag & QUE_BUFTAG_BIT)
1341 return lpfc_sli_ring_taggedbuf_get(phba, pring, tag); 1281 return lpfc_sli_ring_taggedbuf_get(phba, pring, tag);
1342 else 1282 hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
1343 return lpfc_sli_replace_hbqbuff(phba, tag); 1283 if (!hbq_entry)
1284 return NULL;
1285 return &hbq_entry->dbuf;
1344} 1286}
1345 1287
1346 1288
@@ -1372,8 +1314,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1372 match = 0; 1314 match = 0;
1373 irsp = &(saveq->iocb); 1315 irsp = &(saveq->iocb);
1374 1316
1375 if (irsp->ulpStatus == IOSTAT_NEED_BUFFER)
1376 return 1;
1377 if (irsp->ulpCommand == CMD_ASYNC_STATUS) { 1317 if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
1378 if (pring->lpfc_sli_rcv_async_status) 1318 if (pring->lpfc_sli_rcv_async_status)
1379 pring->lpfc_sli_rcv_async_status(phba, pring, saveq); 1319 pring->lpfc_sli_rcv_async_status(phba, pring, saveq);