~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/hosts.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  hosts.c Copyright (C) 1992 Drew Eckhardt
 
3
 *          Copyright (C) 1993, 1994, 1995 Eric Youngdale
 
4
 *          Copyright (C) 2002-2003 Christoph Hellwig
 
5
 *
 
6
 *  mid to lowlevel SCSI driver interface
 
7
 *      Initial versions: Drew Eckhardt
 
8
 *      Subsequent revisions: Eric Youngdale
 
9
 *
 
10
 *  <drew@colorado.edu>
 
11
 *
 
12
 *  Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli
 
13
 *  Added QLOGIC QLA1280 SCSI controller kernel host support. 
 
14
 *     August 4, 1999 Fred Lewis, Intel DuPont
 
15
 *
 
16
 *  Updated to reflect the new initialization scheme for the higher 
 
17
 *  level of scsi drivers (sd/sr/st)
 
18
 *  September 17, 2000 Torben Mathiasen <tmm@image.dk>
 
19
 *
 
20
 *  Restructured scsi_host lists and associated functions.
 
21
 *  September 04, 2002 Mike Anderson (andmike@us.ibm.com)
 
22
 */
 
23
 
 
24
#include <linux/module.h>
 
25
#include <linux/blkdev.h>
 
26
#include <linux/kernel.h>
 
27
#include <linux/slab.h>
 
28
#include <linux/kthread.h>
 
29
#include <linux/string.h>
 
30
#include <linux/mm.h>
 
31
#include <linux/init.h>
 
32
#include <linux/completion.h>
 
33
#include <linux/transport_class.h>
 
34
#include <linux/platform_device.h>
 
35
#include <linux/pm_runtime.h>
 
36
 
 
37
#include <scsi/scsi_device.h>
 
38
#include <scsi/scsi_host.h>
 
39
#include <scsi/scsi_transport.h>
 
40
 
 
41
#include "scsi_priv.h"
 
42
#include "scsi_logging.h"
 
43
 
 
44
 
 
45
static atomic_t scsi_host_next_hn;      /* host_no for next new host */
 
46
 
 
47
 
 
48
static void scsi_host_cls_release(struct device *dev)
 
49
{
 
50
        put_device(&class_to_shost(dev)->shost_gendev);
 
51
}
 
52
 
 
53
static struct class shost_class = {
 
54
        .name           = "scsi_host",
 
55
        .dev_release    = scsi_host_cls_release,
 
56
};
 
57
 
 
58
/**
 
59
 *      scsi_host_set_state - Take the given host through the host state model.
 
60
 *      @shost: scsi host to change the state of.
 
61
 *      @state: state to change to.
 
62
 *
 
63
 *      Returns zero if unsuccessful or an error if the requested
 
64
 *      transition is illegal.
 
65
 **/
 
66
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
 
67
{
 
68
        enum scsi_host_state oldstate = shost->shost_state;
 
69
 
 
70
        if (state == oldstate)
 
71
                return 0;
 
72
 
 
73
        switch (state) {
 
74
        case SHOST_CREATED:
 
75
                /* There are no legal states that come back to
 
76
                 * created.  This is the manually initialised start
 
77
                 * state */
 
78
                goto illegal;
 
79
 
 
80
        case SHOST_RUNNING:
 
81
                switch (oldstate) {
 
82
                case SHOST_CREATED:
 
83
                case SHOST_RECOVERY:
 
84
                        break;
 
85
                default:
 
86
                        goto illegal;
 
87
                }
 
88
                break;
 
89
 
 
90
        case SHOST_RECOVERY:
 
91
                switch (oldstate) {
 
92
                case SHOST_RUNNING:
 
93
                        break;
 
94
                default:
 
95
                        goto illegal;
 
96
                }
 
97
                break;
 
98
 
 
99
        case SHOST_CANCEL:
 
100
                switch (oldstate) {
 
101
                case SHOST_CREATED:
 
102
                case SHOST_RUNNING:
 
103
                case SHOST_CANCEL_RECOVERY:
 
104
                        break;
 
105
                default:
 
106
                        goto illegal;
 
107
                }
 
108
                break;
 
109
 
 
110
        case SHOST_DEL:
 
111
                switch (oldstate) {
 
112
                case SHOST_CANCEL:
 
113
                case SHOST_DEL_RECOVERY:
 
114
                        break;
 
115
                default:
 
116
                        goto illegal;
 
117
                }
 
118
                break;
 
119
 
 
120
        case SHOST_CANCEL_RECOVERY:
 
121
                switch (oldstate) {
 
122
                case SHOST_CANCEL:
 
123
                case SHOST_RECOVERY:
 
124
                        break;
 
125
                default:
 
126
                        goto illegal;
 
127
                }
 
128
                break;
 
129
 
 
130
        case SHOST_DEL_RECOVERY:
 
131
                switch (oldstate) {
 
132
                case SHOST_CANCEL_RECOVERY:
 
133
                        break;
 
134
                default:
 
135
                        goto illegal;
 
136
                }
 
137
                break;
 
138
        }
 
139
        shost->shost_state = state;
 
140
        return 0;
 
141
 
 
142
 illegal:
 
143
        SCSI_LOG_ERROR_RECOVERY(1,
 
144
                                shost_printk(KERN_ERR, shost,
 
145
                                             "Illegal host state transition"
 
146
                                             "%s->%s\n",
 
147
                                             scsi_host_state_name(oldstate),
 
148
                                             scsi_host_state_name(state)));
 
149
        return -EINVAL;
 
150
}
 
151
EXPORT_SYMBOL(scsi_host_set_state);
 
152
 
 
153
/**
 
154
 * scsi_remove_host - remove a scsi host
 
155
 * @shost:      a pointer to a scsi host to remove
 
156
 **/
 
157
void scsi_remove_host(struct Scsi_Host *shost)
 
158
{
 
159
        unsigned long flags;
 
160
 
 
161
        mutex_lock(&shost->scan_mutex);
 
162
        spin_lock_irqsave(shost->host_lock, flags);
 
163
        if (scsi_host_set_state(shost, SHOST_CANCEL))
 
164
                if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
 
165
                        spin_unlock_irqrestore(shost->host_lock, flags);
 
166
                        mutex_unlock(&shost->scan_mutex);
 
167
                        return;
 
168
                }
 
169
        spin_unlock_irqrestore(shost->host_lock, flags);
 
170
 
 
171
        scsi_autopm_get_host(shost);
 
172
        scsi_forget_host(shost);
 
173
        mutex_unlock(&shost->scan_mutex);
 
174
        scsi_proc_host_rm(shost);
 
175
 
 
176
        spin_lock_irqsave(shost->host_lock, flags);
 
177
        if (scsi_host_set_state(shost, SHOST_DEL))
 
178
                BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
 
179
        spin_unlock_irqrestore(shost->host_lock, flags);
 
180
 
 
181
        transport_unregister_device(&shost->shost_gendev);
 
182
        device_unregister(&shost->shost_dev);
 
183
        device_del(&shost->shost_gendev);
 
184
}
 
185
EXPORT_SYMBOL(scsi_remove_host);
 
186
 
 
187
/**
 
188
 * scsi_add_host_with_dma - add a scsi host with dma device
 
189
 * @shost:      scsi host pointer to add
 
190
 * @dev:        a struct device of type scsi class
 
191
 * @dma_dev:    dma device for the host
 
192
 *
 
193
 * Note: You rarely need to worry about this unless you're in a
 
194
 * virtualised host environments, so use the simpler scsi_add_host()
 
195
 * function instead.
 
196
 *
 
197
 * Return value: 
 
198
 *      0 on success / != 0 for error
 
199
 **/
 
200
int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
 
201
                           struct device *dma_dev)
 
202
{
 
203
        struct scsi_host_template *sht = shost->hostt;
 
204
        int error = -EINVAL;
 
205
 
 
206
        printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
 
207
                        sht->info ? sht->info(shost) : sht->name);
 
208
 
 
209
        if (!shost->can_queue) {
 
210
                printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
 
211
                                sht->name);
 
212
                goto fail;
 
213
        }
 
214
 
 
215
        error = scsi_setup_command_freelist(shost);
 
216
        if (error)
 
217
                goto fail;
 
218
 
 
219
        if (!shost->shost_gendev.parent)
 
220
                shost->shost_gendev.parent = dev ? dev : &platform_bus;
 
221
        shost->dma_dev = dma_dev;
 
222
 
 
223
        error = device_add(&shost->shost_gendev);
 
224
        if (error)
 
225
                goto out;
 
226
 
 
227
        pm_runtime_set_active(&shost->shost_gendev);
 
228
        pm_runtime_enable(&shost->shost_gendev);
 
229
        device_enable_async_suspend(&shost->shost_gendev);
 
230
 
 
231
        scsi_host_set_state(shost, SHOST_RUNNING);
 
232
        get_device(shost->shost_gendev.parent);
 
233
 
 
234
        device_enable_async_suspend(&shost->shost_dev);
 
235
 
 
236
        error = device_add(&shost->shost_dev);
 
237
        if (error)
 
238
                goto out_del_gendev;
 
239
 
 
240
        get_device(&shost->shost_gendev);
 
241
 
 
242
        if (shost->transportt->host_size) {
 
243
                shost->shost_data = kzalloc(shost->transportt->host_size,
 
244
                                         GFP_KERNEL);
 
245
                if (shost->shost_data == NULL) {
 
246
                        error = -ENOMEM;
 
247
                        goto out_del_dev;
 
248
                }
 
249
        }
 
250
 
 
251
        if (shost->transportt->create_work_queue) {
 
252
                snprintf(shost->work_q_name, sizeof(shost->work_q_name),
 
253
                         "scsi_wq_%d", shost->host_no);
 
254
                shost->work_q = create_singlethread_workqueue(
 
255
                                        shost->work_q_name);
 
256
                if (!shost->work_q) {
 
257
                        error = -EINVAL;
 
258
                        goto out_free_shost_data;
 
259
                }
 
260
        }
 
261
 
 
262
        error = scsi_sysfs_add_host(shost);
 
263
        if (error)
 
264
                goto out_destroy_host;
 
265
 
 
266
        scsi_proc_host_add(shost);
 
267
        return error;
 
268
 
 
269
 out_destroy_host:
 
270
        if (shost->work_q)
 
271
                destroy_workqueue(shost->work_q);
 
272
 out_free_shost_data:
 
273
        kfree(shost->shost_data);
 
274
 out_del_dev:
 
275
        device_del(&shost->shost_dev);
 
276
 out_del_gendev:
 
277
        device_del(&shost->shost_gendev);
 
278
 out:
 
279
        scsi_destroy_command_freelist(shost);
 
280
 fail:
 
281
        return error;
 
282
}
 
283
EXPORT_SYMBOL(scsi_add_host_with_dma);
 
284
 
 
285
static void scsi_host_dev_release(struct device *dev)
 
286
{
 
287
        struct Scsi_Host *shost = dev_to_shost(dev);
 
288
        struct device *parent = dev->parent;
 
289
        struct request_queue *q;
 
290
 
 
291
        scsi_proc_hostdir_rm(shost->hostt);
 
292
 
 
293
        if (shost->ehandler)
 
294
                kthread_stop(shost->ehandler);
 
295
        if (shost->work_q)
 
296
                destroy_workqueue(shost->work_q);
 
297
        q = shost->uspace_req_q;
 
298
        if (q) {
 
299
                kfree(q->queuedata);
 
300
                q->queuedata = NULL;
 
301
                scsi_free_queue(q);
 
302
        }
 
303
 
 
304
        scsi_destroy_command_freelist(shost);
 
305
        if (shost->bqt)
 
306
                blk_free_tags(shost->bqt);
 
307
 
 
308
        kfree(shost->shost_data);
 
309
 
 
310
        if (parent)
 
311
                put_device(parent);
 
312
        kfree(shost);
 
313
}
 
314
 
 
315
static struct device_type scsi_host_type = {
 
316
        .name =         "scsi_host",
 
317
        .release =      scsi_host_dev_release,
 
318
};
 
319
 
 
320
/**
 
321
 * scsi_host_alloc - register a scsi host adapter instance.
 
322
 * @sht:        pointer to scsi host template
 
323
 * @privsize:   extra bytes to allocate for driver
 
324
 *
 
325
 * Note:
 
326
 *      Allocate a new Scsi_Host and perform basic initialization.
 
327
 *      The host is not published to the scsi midlayer until scsi_add_host
 
328
 *      is called.
 
329
 *
 
330
 * Return value:
 
331
 *      Pointer to a new Scsi_Host
 
332
 **/
 
333
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 
334
{
 
335
        struct Scsi_Host *shost;
 
336
        gfp_t gfp_mask = GFP_KERNEL;
 
337
 
 
338
        if (sht->unchecked_isa_dma && privsize)
 
339
                gfp_mask |= __GFP_DMA;
 
340
 
 
341
        shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
 
342
        if (!shost)
 
343
                return NULL;
 
344
 
 
345
        shost->host_lock = &shost->default_lock;
 
346
        spin_lock_init(shost->host_lock);
 
347
        shost->shost_state = SHOST_CREATED;
 
348
        INIT_LIST_HEAD(&shost->__devices);
 
349
        INIT_LIST_HEAD(&shost->__targets);
 
350
        INIT_LIST_HEAD(&shost->eh_cmd_q);
 
351
        INIT_LIST_HEAD(&shost->starved_list);
 
352
        init_waitqueue_head(&shost->host_wait);
 
353
 
 
354
        mutex_init(&shost->scan_mutex);
 
355
 
 
356
        /*
 
357
         * subtract one because we increment first then return, but we need to
 
358
         * know what the next host number was before increment
 
359
         */
 
360
        shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
 
361
        shost->dma_channel = 0xff;
 
362
 
 
363
        /* These three are default values which can be overridden */
 
364
        shost->max_channel = 0;
 
365
        shost->max_id = 8;
 
366
        shost->max_lun = 8;
 
367
 
 
368
        /* Give each shost a default transportt */
 
369
        shost->transportt = &blank_transport_template;
 
370
 
 
371
        /*
 
372
         * All drivers right now should be able to handle 12 byte
 
373
         * commands.  Every so often there are requests for 16 byte
 
374
         * commands, but individual low-level drivers need to certify that
 
375
         * they actually do something sensible with such commands.
 
376
         */
 
377
        shost->max_cmd_len = 12;
 
378
        shost->hostt = sht;
 
379
        shost->this_id = sht->this_id;
 
380
        shost->can_queue = sht->can_queue;
 
381
        shost->sg_tablesize = sht->sg_tablesize;
 
382
        shost->sg_prot_tablesize = sht->sg_prot_tablesize;
 
383
        shost->cmd_per_lun = sht->cmd_per_lun;
 
384
        shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 
385
        shost->use_clustering = sht->use_clustering;
 
386
        shost->ordered_tag = sht->ordered_tag;
 
387
 
 
388
        if (sht->supported_mode == MODE_UNKNOWN)
 
389
                /* means we didn't set it ... default to INITIATOR */
 
390
                shost->active_mode = MODE_INITIATOR;
 
391
        else
 
392
                shost->active_mode = sht->supported_mode;
 
393
 
 
394
        if (sht->max_host_blocked)
 
395
                shost->max_host_blocked = sht->max_host_blocked;
 
396
        else
 
397
                shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED;
 
398
 
 
399
        /*
 
400
         * If the driver imposes no hard sector transfer limit, start at
 
401
         * machine infinity initially.
 
402
         */
 
403
        if (sht->max_sectors)
 
404
                shost->max_sectors = sht->max_sectors;
 
405
        else
 
406
                shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
 
407
 
 
408
        /*
 
409
         * assume a 4GB boundary, if not set
 
410
         */
 
411
        if (sht->dma_boundary)
 
412
                shost->dma_boundary = sht->dma_boundary;
 
413
        else
 
414
                shost->dma_boundary = 0xffffffff;
 
415
 
 
416
        device_initialize(&shost->shost_gendev);
 
417
        dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
 
418
        shost->shost_gendev.bus = &scsi_bus_type;
 
419
        shost->shost_gendev.type = &scsi_host_type;
 
420
 
 
421
        device_initialize(&shost->shost_dev);
 
422
        shost->shost_dev.parent = &shost->shost_gendev;
 
423
        shost->shost_dev.class = &shost_class;
 
424
        dev_set_name(&shost->shost_dev, "host%d", shost->host_no);
 
425
        shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
 
426
 
 
427
        shost->ehandler = kthread_run(scsi_error_handler, shost,
 
428
                        "scsi_eh_%d", shost->host_no);
 
429
        if (IS_ERR(shost->ehandler)) {
 
430
                printk(KERN_WARNING "scsi%d: error handler thread failed to spawn, error = %ld\n",
 
431
                        shost->host_no, PTR_ERR(shost->ehandler));
 
432
                goto fail_kfree;
 
433
        }
 
434
 
 
435
        scsi_proc_hostdir_add(shost->hostt);
 
436
        return shost;
 
437
 
 
438
 fail_kfree:
 
439
        kfree(shost);
 
440
        return NULL;
 
441
}
 
442
EXPORT_SYMBOL(scsi_host_alloc);
 
443
 
 
444
struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
 
445
{
 
446
        struct Scsi_Host *shost = scsi_host_alloc(sht, privsize);
 
447
 
 
448
        if (!sht->detect) {
 
449
                printk(KERN_WARNING "scsi_register() called on new-style "
 
450
                                    "template for driver %s\n", sht->name);
 
451
                dump_stack();
 
452
        }
 
453
 
 
454
        if (shost)
 
455
                list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
 
456
        return shost;
 
457
}
 
458
EXPORT_SYMBOL(scsi_register);
 
459
 
 
460
void scsi_unregister(struct Scsi_Host *shost)
 
461
{
 
462
        list_del(&shost->sht_legacy_list);
 
463
        scsi_host_put(shost);
 
464
}
 
465
EXPORT_SYMBOL(scsi_unregister);
 
466
 
 
467
static int __scsi_host_match(struct device *dev, void *data)
 
468
{
 
469
        struct Scsi_Host *p;
 
470
        unsigned short *hostnum = (unsigned short *)data;
 
471
 
 
472
        p = class_to_shost(dev);
 
473
        return p->host_no == *hostnum;
 
474
}
 
475
 
 
476
/**
 
477
 * scsi_host_lookup - get a reference to a Scsi_Host by host no
 
478
 * @hostnum:    host number to locate
 
479
 *
 
480
 * Return value:
 
481
 *      A pointer to located Scsi_Host or NULL.
 
482
 *
 
483
 *      The caller must do a scsi_host_put() to drop the reference
 
484
 *      that scsi_host_get() took. The put_device() below dropped
 
485
 *      the reference from class_find_device().
 
486
 **/
 
487
struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
 
488
{
 
489
        struct device *cdev;
 
490
        struct Scsi_Host *shost = NULL;
 
491
 
 
492
        cdev = class_find_device(&shost_class, NULL, &hostnum,
 
493
                                 __scsi_host_match);
 
494
        if (cdev) {
 
495
                shost = scsi_host_get(class_to_shost(cdev));
 
496
                put_device(cdev);
 
497
        }
 
498
        return shost;
 
499
}
 
500
EXPORT_SYMBOL(scsi_host_lookup);
 
501
 
 
502
/**
 
503
 * scsi_host_get - inc a Scsi_Host ref count
 
504
 * @shost:      Pointer to Scsi_Host to inc.
 
505
 **/
 
506
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
 
507
{
 
508
        if ((shost->shost_state == SHOST_DEL) ||
 
509
                !get_device(&shost->shost_gendev))
 
510
                return NULL;
 
511
        return shost;
 
512
}
 
513
EXPORT_SYMBOL(scsi_host_get);
 
514
 
 
515
/**
 
516
 * scsi_host_put - dec a Scsi_Host ref count
 
517
 * @shost:      Pointer to Scsi_Host to dec.
 
518
 **/
 
519
void scsi_host_put(struct Scsi_Host *shost)
 
520
{
 
521
        put_device(&shost->shost_gendev);
 
522
}
 
523
EXPORT_SYMBOL(scsi_host_put);
 
524
 
 
525
int scsi_init_hosts(void)
 
526
{
 
527
        return class_register(&shost_class);
 
528
}
 
529
 
 
530
void scsi_exit_hosts(void)
 
531
{
 
532
        class_unregister(&shost_class);
 
533
}
 
534
 
 
535
int scsi_is_host_device(const struct device *dev)
 
536
{
 
537
        return dev->type == &scsi_host_type;
 
538
}
 
539
EXPORT_SYMBOL(scsi_is_host_device);
 
540
 
 
541
/**
 
542
 * scsi_queue_work - Queue work to the Scsi_Host workqueue.
 
543
 * @shost:      Pointer to Scsi_Host.
 
544
 * @work:       Work to queue for execution.
 
545
 *
 
546
 * Return value:
 
547
 *      1 - work queued for execution
 
548
 *      0 - work is already queued
 
549
 *      -EINVAL - work queue doesn't exist
 
550
 **/
 
551
int scsi_queue_work(struct Scsi_Host *shost, struct work_struct *work)
 
552
{
 
553
        if (unlikely(!shost->work_q)) {
 
554
                printk(KERN_ERR
 
555
                        "ERROR: Scsi host '%s' attempted to queue scsi-work, "
 
556
                        "when no workqueue created.\n", shost->hostt->name);
 
557
                dump_stack();
 
558
 
 
559
                return -EINVAL;
 
560
        }
 
561
 
 
562
        return queue_work(shost->work_q, work);
 
563
}
 
564
EXPORT_SYMBOL_GPL(scsi_queue_work);
 
565
 
 
566
/**
 
567
 * scsi_flush_work - Flush a Scsi_Host's workqueue.
 
568
 * @shost:      Pointer to Scsi_Host.
 
569
 **/
 
570
void scsi_flush_work(struct Scsi_Host *shost)
 
571
{
 
572
        if (!shost->work_q) {
 
573
                printk(KERN_ERR
 
574
                        "ERROR: Scsi host '%s' attempted to flush scsi-work, "
 
575
                        "when no workqueue created.\n", shost->hostt->name);
 
576
                dump_stack();
 
577
                return;
 
578
        }
 
579
 
 
580
        flush_workqueue(shost->work_q);
 
581
}
 
582
EXPORT_SYMBOL_GPL(scsi_flush_work);