scsi_scan.c (d3e4cefc86ce1aefc0e9aebdc56308cb4bd51997) | scsi_scan.c (863a930a40eb7f2d18534c2c166b22582f5c6cfd) |
---|---|
1/* 2 * scsi_scan.c 3 * 4 * Copyright (C) 2000 Eric Youngdale, 5 * Copyright (C) 2002 Patrick Mansfield 6 * 7 * The general scanning/probing algorithm is as follows, exceptions are 8 * made to it depending on device specific flags, compilation options, and --- 386 unchanged lines hidden (view full) --- 395 found: 396 found_target->reap_ref++; 397 spin_unlock_irqrestore(shost->host_lock, flags); 398 put_device(parent); 399 kfree(starget); 400 return found_target; 401} 402 | 1/* 2 * scsi_scan.c 3 * 4 * Copyright (C) 2000 Eric Youngdale, 5 * Copyright (C) 2002 Patrick Mansfield 6 * 7 * The general scanning/probing algorithm is as follows, exceptions are 8 * made to it depending on device specific flags, compilation options, and --- 386 unchanged lines hidden (view full) --- 395 found: 396 found_target->reap_ref++; 397 spin_unlock_irqrestore(shost->host_lock, flags); 398 put_device(parent); 399 kfree(starget); 400 return found_target; 401} 402 |
403struct work_queue_wrapper { 404 struct work_struct work; 405 struct scsi_target *starget; 406}; 407 408static void scsi_target_reap_work(void *data) { 409 struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; 410 struct scsi_target *starget = wqw->starget; 411 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 412 unsigned long flags; 413 414 kfree(wqw); 415 416 spin_lock_irqsave(shost->host_lock, flags); 417 418 if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { 419 list_del_init(&starget->siblings); 420 spin_unlock_irqrestore(shost->host_lock, flags); 421 device_del(&starget->dev); 422 transport_unregister_device(&starget->dev); 423 put_device(&starget->dev); 424 return; 425 426 } 427 spin_unlock_irqrestore(shost->host_lock, flags); 428 429 return; 430} 431 |
|
403/** 404 * scsi_target_reap - check to see if target is in use and destroy if not 405 * 406 * @starget: target to be checked 407 * 408 * This is used after removing a LUN or doing a last put of the target 409 * it checks atomically that nothing is using the target and removes 410 * it if so. 411 */ 412void scsi_target_reap(struct scsi_target *starget) 413{ | 432/** 433 * scsi_target_reap - check to see if target is in use and destroy if not 434 * 435 * @starget: target to be checked 436 * 437 * This is used after removing a LUN or doing a last put of the target 438 * it checks atomically that nothing is using the target and removes 439 * it if so. 440 */ 441void scsi_target_reap(struct scsi_target *starget) 442{ |
414 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 415 unsigned long flags; 416 spin_lock_irqsave(shost->host_lock, flags); | 443 struct work_queue_wrapper *wqw = 444 kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); |
417 | 445 |
418 if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { 419 list_del_init(&starget->siblings); 420 spin_unlock_irqrestore(shost->host_lock, flags); 421 device_del(&starget->dev); 422 transport_unregister_device(&starget->dev); 423 put_device(&starget->dev); | 446 if (!wqw) { 447 starget_printk(KERN_ERR, starget, 448 "Failed to allocate memory in scsi_reap_target()\n"); |
424 return; 425 } | 449 return; 450 } |
426 spin_unlock_irqrestore(shost->host_lock, flags); | 451 452 INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); 453 wqw->starget = starget; 454 schedule_work(&wqw->work); |
427} 428 429/** 430 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 431 * @sdev: scsi_device to probe 432 * @inq_result: area to store the INQUIRY result 433 * @result_len: len of inq_result 434 * @bflags: store any bflags found here --- 1101 unchanged lines hidden --- | 455} 456 457/** 458 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 459 * @sdev: scsi_device to probe 460 * @inq_result: area to store the INQUIRY result 461 * @result_len: len of inq_result 462 * @bflags: store any bflags found here --- 1101 unchanged lines hidden --- |