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 ---