Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 188305
b: refs/heads/master
c: 3146840
h: refs/heads/master
i:
  188303: 81ec2fa
v: v3
  • Loading branch information
Mike Miller authored and James Bottomley committed Mar 3, 2010
1 parent eae0acf commit 09cdc2d
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 167 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: e9ea04a65ad842452cbee92b5c865af7fed17f63
refs/heads/master: 31468401ccf64322ca99fe05fbe64f1551240f57
167 changes: 4 additions & 163 deletions trunk/drivers/scsi/hpsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
#include "hpsa.h"

/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
#define HPSA_DRIVER_VERSION "2.0.1-3"
#define HPSA_DRIVER_VERSION "2.0.2-1"
#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"

/* How long to wait (in milliseconds) for board to go into simple mode */
Expand Down Expand Up @@ -212,133 +212,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
return (struct ctlr_info *) *priv;
}

static struct task_struct *hpsa_scan_thread;
static DEFINE_MUTEX(hpsa_scan_mutex);
static LIST_HEAD(hpsa_scan_q);
static int hpsa_scan_func(void *data);

/**
* add_to_scan_list() - add controller to rescan queue
* @h: Pointer to the controller.
*
* Adds the controller to the rescan queue if not already on the queue.
*
* returns 1 if added to the queue, 0 if skipped (could be on the
* queue already, or the controller could be initializing or shutting
* down).
**/
static int add_to_scan_list(struct ctlr_info *h)
{
struct ctlr_info *test_h;
int found = 0;
int ret = 0;

if (h->busy_initializing)
return 0;

/*
* If we don't get the lock, it means the driver is unloading
* and there's no point in scheduling a new scan.
*/
if (!mutex_trylock(&h->busy_shutting_down))
return 0;

mutex_lock(&hpsa_scan_mutex);
list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
if (test_h == h) {
found = 1;
break;
}
}
if (!found && !h->busy_scanning) {
INIT_COMPLETION(h->scan_wait);
list_add_tail(&h->scan_list, &hpsa_scan_q);
ret = 1;
}
mutex_unlock(&hpsa_scan_mutex);
mutex_unlock(&h->busy_shutting_down);

return ret;
}

/**
* remove_from_scan_list() - remove controller from rescan queue
* @h: Pointer to the controller.
*
* Removes the controller from the rescan queue if present. Blocks if
* the controller is currently conducting a rescan. The controller
* can be in one of three states:
* 1. Doesn't need a scan
* 2. On the scan list, but not scanning yet (we remove it)
* 3. Busy scanning (and not on the list). In this case we want to wait for
* the scan to complete to make sure the scanning thread for this
* controller is completely idle.
**/
static void remove_from_scan_list(struct ctlr_info *h)
{
struct ctlr_info *test_h, *tmp_h;

mutex_lock(&hpsa_scan_mutex);
list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
if (test_h == h) { /* state 2. */
list_del(&h->scan_list);
complete_all(&h->scan_wait);
mutex_unlock(&hpsa_scan_mutex);
return;
}
}
if (h->busy_scanning) { /* state 3. */
mutex_unlock(&hpsa_scan_mutex);
wait_for_completion(&h->scan_wait);
} else { /* state 1, nothing to do. */
mutex_unlock(&hpsa_scan_mutex);
}
}

/* hpsa_scan_func() - kernel thread used to rescan controllers
* @data: Ignored.
*
* A kernel thread used scan for drive topology changes on
* controllers. The thread processes only one controller at a time
* using a queue. Controllers are added to the queue using
* add_to_scan_list() and removed from the queue either after done
* processing or using remove_from_scan_list().
*
* returns 0.
**/
static int hpsa_scan_func(__attribute__((unused)) void *data)
{
struct ctlr_info *h;
int host_no;

while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
if (kthread_should_stop())
break;

while (1) {
mutex_lock(&hpsa_scan_mutex);
if (list_empty(&hpsa_scan_q)) {
mutex_unlock(&hpsa_scan_mutex);
break;
}
h = list_entry(hpsa_scan_q.next, struct ctlr_info,
scan_list);
list_del(&h->scan_list);
h->busy_scanning = 1;
mutex_unlock(&hpsa_scan_mutex);
host_no = h->scsi_host ? h->scsi_host->host_no : -1;
hpsa_scan_start(h->scsi_host);
complete_all(&h->scan_wait);
mutex_lock(&hpsa_scan_mutex);
h->busy_scanning = 0;
mutex_unlock(&hpsa_scan_mutex);
}
}
return 0;
}

static int check_for_unit_attention(struct ctlr_info *h,
struct CommandList *c)
{
Expand All @@ -356,21 +229,8 @@ static int check_for_unit_attention(struct ctlr_info *h,
break;
case REPORT_LUNS_CHANGED:
dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
"changed\n", h->ctlr);
"changed, action required\n", h->ctlr);
/*
* Here, we could call add_to_scan_list and wake up the scan thread,
* except that it's quite likely that we will get more than one
* REPORT_LUNS_CHANGED condition in quick succession, which means
* that those which occur after the first one will likely happen
* *during* the hpsa_scan_thread's rescan. And the rescan code is not
* robust enough to restart in the middle, undoing what it has already
* done, and it's not clear that it's even possible to do this, since
* part of what it does is notify the SCSI mid layer, which starts
* doing it's own i/o to read partition tables and so on, and the
* driver doesn't have visibility to know what might need undoing.
* In any event, if possible, it is horribly complicated to get right
* so we just don't do it for now.
*
* Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
*/
break;
Expand All @@ -397,10 +257,7 @@ static ssize_t host_store_rescan(struct device *dev,
struct ctlr_info *h;
struct Scsi_Host *shost = class_to_shost(dev);
h = shost_to_hba(shost);
if (add_to_scan_list(h)) {
wake_up_process(hpsa_scan_thread);
wait_for_completion_interruptible(&h->scan_wait);
}
hpsa_scan_start(h->scsi_host);
return count;
}

Expand Down Expand Up @@ -3553,8 +3410,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
h->busy_initializing = 1;
INIT_HLIST_HEAD(&h->cmpQ);
INIT_HLIST_HEAD(&h->reqQ);
mutex_init(&h->busy_shutting_down);
init_completion(&h->scan_wait);
rc = hpsa_pci_init(h, pdev);
if (rc != 0)
goto clean1;
Expand Down Expand Up @@ -3702,8 +3557,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
return;
}
h = pci_get_drvdata(pdev);
mutex_lock(&h->busy_shutting_down);
remove_from_scan_list(h);
hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */
hpsa_shutdown(pdev);
iounmap(h->vaddr);
Expand All @@ -3724,7 +3577,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
*/
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
mutex_unlock(&h->busy_shutting_down);
kfree(h);
}

Expand Down Expand Up @@ -3878,23 +3730,12 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
*/
static int __init hpsa_init(void)
{
int err;
/* Start the scan thread */
hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
if (IS_ERR(hpsa_scan_thread)) {
err = PTR_ERR(hpsa_scan_thread);
return -ENODEV;
}
err = pci_register_driver(&hpsa_pci_driver);
if (err)
kthread_stop(hpsa_scan_thread);
return err;
return pci_register_driver(&hpsa_pci_driver);
}

static void __exit hpsa_cleanup(void)
{
pci_unregister_driver(&hpsa_pci_driver);
kthread_stop(hpsa_scan_thread);
}

module_init(hpsa_init);
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/scsi/hpsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ struct ctlr_info {
int scan_finished;
spinlock_t scan_lock;
wait_queue_head_t scan_wait_queue;
struct mutex busy_shutting_down;
struct list_head scan_list;
struct completion scan_wait;

struct Scsi_Host *scsi_host;
spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */
Expand Down

0 comments on commit 09cdc2d

Please sign in to comment.