aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-06-24 16:11:53 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:43:06 -0400
commitf457a46f179df41b0f6d80dee33b6e629945f276 (patch)
treeacbeac8630b898610fe71295f11cbc71f956b8ba /drivers/scsi/be2iscsi
parent9d04516310aaef3970c642a54531a52123001178 (diff)
[SCSI] iscsi_ibft, be2iscsi, iscsi_boot: fix boot kobj data lifetime management
be2iscsi passes the boot functions its phba object which is allocated in the shost, but iscsi_ibft passes in a object allocated for each item to display. The problem is that iscsi_boot_sysfs was managing the lifetime of the object passed in and doing a kfree on release. This causes a double free for be2iscsi which frees the shost in its pci_remove. This patch fixes the problem by adding a release callback which the drivers can call kfree or a put() type of function (needed for be2iscsi which will do a get/put on the shost). Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be_main.c190
1 files changed, 99 insertions, 91 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 2e214390c63b..0a9bdfa3d939 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -215,73 +215,62 @@ unlock:
215static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) 215static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
216{ 216{
217 struct beiscsi_hba *phba = data; 217 struct beiscsi_hba *phba = data;
218 struct mgmt_session_info *boot_sess = &phba->boot_sess;
219 struct mgmt_conn_info *boot_conn = &boot_sess->conn_list[0];
218 char *str = buf; 220 char *str = buf;
219 int rc; 221 int rc;
220 222
221 switch (type) { 223 switch (type) {
222 case ISCSI_BOOT_TGT_NAME: 224 case ISCSI_BOOT_TGT_NAME:
223 rc = sprintf(buf, "%.*s\n", 225 rc = sprintf(buf, "%.*s\n",
224 (int)strlen(phba->boot_sess.target_name), 226 (int)strlen(boot_sess->target_name),
225 (char *)&phba->boot_sess.target_name); 227 (char *)&boot_sess->target_name);
226 break; 228 break;
227 case ISCSI_BOOT_TGT_IP_ADDR: 229 case ISCSI_BOOT_TGT_IP_ADDR:
228 if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1) 230 if (boot_conn->dest_ipaddr.ip_type == 0x1)
229 rc = sprintf(buf, "%pI4\n", 231 rc = sprintf(buf, "%pI4\n",
230 (char *)&phba->boot_sess.conn_list[0]. 232 (char *)&boot_conn->dest_ipaddr.ip_address);
231 dest_ipaddr.ip_address);
232 else 233 else
233 rc = sprintf(str, "%pI6\n", 234 rc = sprintf(str, "%pI6\n",
234 (char *)&phba->boot_sess.conn_list[0]. 235 (char *)&boot_conn->dest_ipaddr.ip_address);
235 dest_ipaddr.ip_address);
236 break; 236 break;
237 case ISCSI_BOOT_TGT_PORT: 237 case ISCSI_BOOT_TGT_PORT:
238 rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0]. 238 rc = sprintf(str, "%d\n", boot_conn->dest_port);
239 dest_port);
240 break; 239 break;
241 240
242 case ISCSI_BOOT_TGT_CHAP_NAME: 241 case ISCSI_BOOT_TGT_CHAP_NAME:
243 rc = sprintf(str, "%.*s\n", 242 rc = sprintf(str, "%.*s\n",
244 phba->boot_sess.conn_list[0]. 243 boot_conn->negotiated_login_options.auth_data.chap.
245 negotiated_login_options.auth_data.chap. 244 target_chap_name_length,
246 target_chap_name_length, 245 (char *)&boot_conn->negotiated_login_options.
247 (char *)&phba->boot_sess.conn_list[0]. 246 auth_data.chap.target_chap_name);
248 negotiated_login_options.auth_data.chap.
249 target_chap_name);
250 break; 247 break;
251 case ISCSI_BOOT_TGT_CHAP_SECRET: 248 case ISCSI_BOOT_TGT_CHAP_SECRET:
252 rc = sprintf(str, "%.*s\n", 249 rc = sprintf(str, "%.*s\n",
253 phba->boot_sess.conn_list[0]. 250 boot_conn->negotiated_login_options.auth_data.chap.
254 negotiated_login_options.auth_data.chap. 251 target_secret_length,
255 target_secret_length, 252 (char *)&boot_conn->negotiated_login_options.
256 (char *)&phba->boot_sess.conn_list[0]. 253 auth_data.chap.target_secret);
257 negotiated_login_options.auth_data.chap.
258 target_secret);
259
260 break; 254 break;
261 case ISCSI_BOOT_TGT_REV_CHAP_NAME: 255 case ISCSI_BOOT_TGT_REV_CHAP_NAME:
262 rc = sprintf(str, "%.*s\n", 256 rc = sprintf(str, "%.*s\n",
263 phba->boot_sess.conn_list[0]. 257 boot_conn->negotiated_login_options.auth_data.chap.
264 negotiated_login_options.auth_data.chap. 258 intr_chap_name_length,
265 intr_chap_name_length, 259 (char *)&boot_conn->negotiated_login_options.
266 (char *)&phba->boot_sess.conn_list[0]. 260 auth_data.chap.intr_chap_name);
267 negotiated_login_options.auth_data.chap.
268 intr_chap_name);
269
270 break; 261 break;
271 case ISCSI_BOOT_TGT_REV_CHAP_SECRET: 262 case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
272 rc = sprintf(str, "%.*s\n", 263 rc = sprintf(str, "%.*s\n",
273 phba->boot_sess.conn_list[0]. 264 boot_conn->negotiated_login_options.auth_data.chap.
274 negotiated_login_options.auth_data.chap. 265 intr_secret_length,
275 intr_secret_length, 266 (char *)&boot_conn->negotiated_login_options.
276 (char *)&phba->boot_sess.conn_list[0]. 267 auth_data.chap.intr_secret);
277 negotiated_login_options.auth_data.chap.
278 intr_secret);
279 break; 268 break;
280 case ISCSI_BOOT_TGT_FLAGS: 269 case ISCSI_BOOT_TGT_FLAGS:
281 rc = sprintf(str, "2\n"); 270 rc = sprintf(str, "2\n");
282 break; 271 break;
283 case ISCSI_BOOT_TGT_NIC_ASSOC: 272 case ISCSI_BOOT_TGT_NIC_ASSOC:
284 rc = sprintf(str, "0\n"); 273 rc = sprintf(str, "0\n");
285 break; 274 break;
286 default: 275 default:
287 rc = -ENOSYS; 276 rc = -ENOSYS;
@@ -315,10 +304,10 @@ static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
315 304
316 switch (type) { 305 switch (type) {
317 case ISCSI_BOOT_ETH_FLAGS: 306 case ISCSI_BOOT_ETH_FLAGS:
318 rc = sprintf(str, "2\n"); 307 rc = sprintf(str, "2\n");
319 break; 308 break;
320 case ISCSI_BOOT_ETH_INDEX: 309 case ISCSI_BOOT_ETH_INDEX:
321 rc = sprintf(str, "0\n"); 310 rc = sprintf(str, "0\n");
322 break; 311 break;
323 case ISCSI_BOOT_ETH_MAC: 312 case ISCSI_BOOT_ETH_MAC:
324 rc = beiscsi_get_macaddr(buf, phba); 313 rc = beiscsi_get_macaddr(buf, phba);
@@ -391,39 +380,6 @@ static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
391 return rc; 380 return rc;
392} 381}
393 382
394static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
395{
396 struct iscsi_boot_kobj *boot_kobj;
397
398 phba->boot_kset = iscsi_boot_create_host_kset(phba->shost->host_no);
399 if (!phba->boot_kset)
400 return -ENOMEM;
401
402 /* get boot info using mgmt cmd */
403 boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
404 beiscsi_show_boot_tgt_info,
405 beiscsi_tgt_get_attr_visibility);
406 if (!boot_kobj)
407 goto free_kset;
408
409 boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
410 beiscsi_show_boot_ini_info,
411 beiscsi_ini_get_attr_visibility);
412 if (!boot_kobj)
413 goto free_kset;
414
415 boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
416 beiscsi_show_boot_eth_info,
417 beiscsi_eth_get_attr_visibility);
418 if (!boot_kobj)
419 goto free_kset;
420 return 0;
421
422free_kset:
423 iscsi_boot_destroy_kset(phba->boot_kset);
424 return -ENOMEM;
425}
426
427/*------------------- PCI Driver operations and data ----------------- */ 383/*------------------- PCI Driver operations and data ----------------- */
428static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { 384static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
429 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 385 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -482,14 +438,6 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
482 if (iscsi_host_add(shost, &phba->pcidev->dev)) 438 if (iscsi_host_add(shost, &phba->pcidev->dev))
483 goto free_devices; 439 goto free_devices;
484 440
485 if (beiscsi_setup_boot_info(phba))
486 /*
487 * log error but continue, because we may not be using
488 * iscsi boot.
489 */
490 shost_printk(KERN_ERR, phba->shost, "Could not set up "
491 "iSCSI boot info.");
492
493 return phba; 441 return phba;
494 442
495free_devices: 443free_devices:
@@ -3510,6 +3458,7 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3510 unsigned int tag, wrb_num; 3458 unsigned int tag, wrb_num;
3511 unsigned short status, extd_status; 3459 unsigned short status, extd_status;
3512 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 3460 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
3461 int ret = -ENOMEM;
3513 3462
3514 tag = beiscsi_get_boot_target(phba); 3463 tag = beiscsi_get_boot_target(phba);
3515 if (!tag) { 3464 if (!tag) {
@@ -3534,8 +3483,7 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3534 boot_resp = embedded_payload(wrb); 3483 boot_resp = embedded_payload(wrb);
3535 3484
3536 if (boot_resp->boot_session_handle < 0) { 3485 if (boot_resp->boot_session_handle < 0) {
3537 printk(KERN_ERR "No Boot Session for this pci_func," 3486 shost_printk(KERN_INFO, phba->shost, "No Boot Session.\n");
3538 "session Hndl = %d\n", boot_resp->boot_session_handle);
3539 return -ENXIO; 3487 return -ENXIO;
3540 } 3488 }
3541 3489
@@ -3573,14 +3521,70 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3573 wrb = queue_get_wrb(mccq, wrb_num); 3521 wrb = queue_get_wrb(mccq, wrb_num);
3574 free_mcc_tag(&phba->ctrl, tag); 3522 free_mcc_tag(&phba->ctrl, tag);
3575 session_resp = nonemb_cmd.va ; 3523 session_resp = nonemb_cmd.va ;
3524
3576 memcpy(&phba->boot_sess, &session_resp->session_info, 3525 memcpy(&phba->boot_sess, &session_resp->session_info,
3577 sizeof(struct mgmt_session_info)); 3526 sizeof(struct mgmt_session_info));
3578 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 3527 ret = 0;
3579 nonemb_cmd.va, nonemb_cmd.dma); 3528
3580 return 0;
3581boot_freemem: 3529boot_freemem:
3582 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 3530 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
3583 nonemb_cmd.va, nonemb_cmd.dma); 3531 nonemb_cmd.va, nonemb_cmd.dma);
3532 return ret;
3533}
3534
3535static void beiscsi_boot_release(void *data)
3536{
3537 struct beiscsi_hba *phba = data;
3538
3539 scsi_host_put(phba->shost);
3540}
3541
3542static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
3543{
3544 struct iscsi_boot_kobj *boot_kobj;
3545
3546 /* get boot info using mgmt cmd */
3547 if (beiscsi_get_boot_info(phba))
3548 /* Try to see if we can carry on without this */
3549 return 0;
3550
3551 phba->boot_kset = iscsi_boot_create_host_kset(phba->shost->host_no);
3552 if (!phba->boot_kset)
3553 return -ENOMEM;
3554
3555 /* get a ref because the show function will ref the phba */
3556 if (!scsi_host_get(phba->shost))
3557 goto free_kset;
3558 boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
3559 beiscsi_show_boot_tgt_info,
3560 beiscsi_tgt_get_attr_visibility,
3561 beiscsi_boot_release);
3562 if (!boot_kobj)
3563 goto put_shost;
3564
3565 if (!scsi_host_get(phba->shost))
3566 goto free_kset;
3567 boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
3568 beiscsi_show_boot_ini_info,
3569 beiscsi_ini_get_attr_visibility,
3570 beiscsi_boot_release);
3571 if (!boot_kobj)
3572 goto put_shost;
3573
3574 if (!scsi_host_get(phba->shost))
3575 goto free_kset;
3576 boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
3577 beiscsi_show_boot_eth_info,
3578 beiscsi_eth_get_attr_visibility,
3579 beiscsi_boot_release);
3580 if (!boot_kobj)
3581 goto put_shost;
3582 return 0;
3583
3584put_shost:
3585 scsi_host_put(phba->shost);
3586free_kset:
3587 iscsi_boot_destroy_kset(phba->boot_kset);
3584 return -ENOMEM; 3588 return -ENOMEM;
3585} 3589}
3586 3590
@@ -4307,11 +4311,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
4307 goto free_blkenbld; 4311 goto free_blkenbld;
4308 } 4312 }
4309 hwi_enable_intr(phba); 4313 hwi_enable_intr(phba);
4310 ret = beiscsi_get_boot_info(phba); 4314
4311 if (ret < 0) { 4315 if (beiscsi_setup_boot_info(phba))
4312 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 4316 /*
4313 "No Boot Devices !!!!!\n"); 4317 * log error but continue, because we may not be using
4314 } 4318 * iscsi boot.
4319 */
4320 shost_printk(KERN_ERR, phba->shost, "Could not set up "
4321 "iSCSI boot info.");
4322
4315 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); 4323 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
4316 return 0; 4324 return 0;
4317 4325