Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 84387
b: refs/heads/master
c: 8aae18a
h: refs/heads/master
i:
  84385: f0962c8
  84383: 149ed78
v: v3
  • Loading branch information
Mike Christie authored and James Bottomley committed Feb 8, 2008
1 parent 120658d commit 853ff7b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 568d303b5b3f0f6432ae8f56ecdb0beb2341288e
refs/heads/master: 8aae18adb240a9eb1999b8245c56522cbefc9047
38 changes: 35 additions & 3 deletions trunk/drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
memset(ihost, 0, sizeof(*ihost));
INIT_LIST_HEAD(&ihost->sessions);
mutex_init(&ihost->mutex);
atomic_set(&ihost->nr_scans, 0);

snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
shost->host_no);
Expand Down Expand Up @@ -284,6 +285,25 @@ static int iscsi_is_session_dev(const struct device *dev)
return dev->release == iscsi_session_release;
}

/**
* iscsi_scan_finished - helper to report when running scans are done
* @shost: scsi host
* @time: scan run time
*
* This function can be used by drives like qla4xxx to report to the scsi
* layer when the scans it kicked off at module load time are done.
*/
int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
struct iscsi_host *ihost = shost->shost_data;
/*
* qla4xxx will have kicked off some session unblocks before calling
* scsi_scan_host, so just wait for them to complete.
*/
return !atomic_read(&ihost->nr_scans);
}
EXPORT_SYMBOL_GPL(iscsi_scan_finished);

static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
uint id, uint lun)
{
Expand All @@ -306,17 +326,21 @@ static void iscsi_scan_session(struct work_struct *work)
{
struct iscsi_cls_session *session =
container_of(work, struct iscsi_cls_session, scan_work);
struct Scsi_Host *shost = iscsi_session_to_shost(session);
struct iscsi_host *ihost = shost->shost_data;
unsigned long flags;

spin_lock_irqsave(&session->lock, flags);
if (session->state != ISCSI_SESSION_LOGGED_IN) {
spin_unlock_irqrestore(&session->lock, flags);
return;
goto done;
}
spin_unlock_irqrestore(&session->lock, flags);

scsi_scan_target(&session->dev, 0, session->target_id,
SCAN_WILD_CARD, 1);
done:
atomic_dec(&ihost->nr_scans);
}

static void session_recovery_timedout(struct work_struct *work)
Expand Down Expand Up @@ -366,7 +390,15 @@ void iscsi_unblock_session(struct iscsi_cls_session *session)
spin_unlock_irqrestore(&session->lock, flags);

__iscsi_unblock_session(session);
queue_work(ihost->scan_workq, &session->scan_work);
/*
* Only do kernel scanning if the driver is properly hooked into
* the async scanning code (drivers like iscsi_tcp do login and
* scanning from userspace).
*/
if (shost->hostt->scan_finished) {
if (queue_work(ihost->scan_workq, &session->scan_work))
atomic_inc(&ihost->nr_scans);
}
}
EXPORT_SYMBOL_GPL(iscsi_unblock_session);

Expand Down Expand Up @@ -550,7 +582,7 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
session->state = ISCSI_SESSION_FREE;
spin_unlock_irqrestore(&session->lock, flags);
__iscsi_unblock_session(session);
iscsi_unbind_session(session);
__iscsi_unbind_session(&session->unbind_work);

/* flush running scans */
flush_workqueue(ihost->scan_workq);
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/scsi/scsi_transport_iscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ struct iscsi_cls_session {

struct iscsi_host {
struct list_head sessions;
atomic_t nr_scans;
struct mutex mutex;
struct workqueue_struct *scan_workq;
char scan_workq_name[KOBJ_NAME_LEN];
Expand All @@ -229,6 +230,6 @@ extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
extern void iscsi_block_session(struct iscsi_cls_session *session);

extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);

#endif

0 comments on commit 853ff7b

Please sign in to comment.