]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/scsi/scsi_tgt_lib.c
Merge branch 'linux-2.6'
[linux-2.6-omap-h63xx.git] / drivers / scsi / scsi_tgt_lib.c
1 /*
2  * SCSI target lib functions
3  *
4  * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
5  * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22 #include <linux/blkdev.h>
23 #include <linux/hash.h>
24 #include <linux/module.h>
25 #include <linux/pagemap.h>
26 #include <scsi/scsi.h>
27 #include <scsi/scsi_cmnd.h>
28 #include <scsi/scsi_device.h>
29 #include <scsi/scsi_host.h>
30 #include <scsi/scsi_tgt.h>
31
32 #include "scsi_tgt_priv.h"
33
34 static struct workqueue_struct *scsi_tgtd;
35 static struct kmem_cache *scsi_tgt_cmd_cache;
36
37 /*
38  * TODO: this struct will be killed when the block layer supports large bios
39  * and James's work struct code is in
40  */
41 struct scsi_tgt_cmd {
42         /* TODO replace work with James b's code */
43         struct work_struct work;
44         /* TODO fix limits of some drivers */
45         struct bio *bio;
46
47         struct list_head hash_list;
48         struct request *rq;
49         u64 tag;
50 };
51
52 #define TGT_HASH_ORDER  4
53 #define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER)
54
55 struct scsi_tgt_queuedata {
56         struct Scsi_Host *shost;
57         struct list_head cmd_hash[1 << TGT_HASH_ORDER];
58         spinlock_t cmd_hash_lock;
59 };
60
61 /*
62  * Function:    scsi_host_get_command()
63  *
64  * Purpose:     Allocate and setup a scsi command block and blk request
65  *
66  * Arguments:   shost   - scsi host
67  *              data_dir - dma data dir
68  *              gfp_mask- allocator flags
69  *
70  * Returns:     The allocated scsi command structure.
71  *
72  * This should be called by target LLDs to get a command.
73  */
74 struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
75                                         enum dma_data_direction data_dir,
76                                         gfp_t gfp_mask)
77 {
78         int write = (data_dir == DMA_TO_DEVICE);
79         struct request *rq;
80         struct scsi_cmnd *cmd;
81         struct scsi_tgt_cmd *tcmd;
82
83         /* Bail if we can't get a reference to the device */
84         if (!get_device(&shost->shost_gendev))
85                 return NULL;
86
87         tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC);
88         if (!tcmd)
89                 goto put_dev;
90
91         /*
92          * The blk helpers are used to the READ/WRITE requests
93          * transfering data from a initiator point of view. Since
94          * we are in target mode we want the opposite.
95          */
96         rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask);
97         if (!rq)
98                 goto free_tcmd;
99
100         cmd = __scsi_get_command(shost, gfp_mask);
101         if (!cmd)
102                 goto release_rq;
103
104         memset(cmd, 0, sizeof(*cmd));
105         cmd->sc_data_direction = data_dir;
106         cmd->jiffies_at_alloc = jiffies;
107         cmd->request = rq;
108
109         rq->special = cmd;
110         rq->cmd_type = REQ_TYPE_SPECIAL;
111         rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
112         rq->end_io_data = tcmd;
113
114         tcmd->rq = rq;
115
116         return cmd;
117
118 release_rq:
119         blk_put_request(rq);
120 free_tcmd:
121         kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
122 put_dev:
123         put_device(&shost->shost_gendev);
124         return NULL;
125
126 }
127 EXPORT_SYMBOL_GPL(scsi_host_get_command);
128
129 /*
130  * Function:    scsi_host_put_command()
131  *
132  * Purpose:     Free a scsi command block
133  *
134  * Arguments:   shost   - scsi host
135  *              cmd     - command block to free
136  *
137  * Returns:     Nothing.
138  *
139  * Notes:       The command must not belong to any lists.
140  */
141 void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
142 {
143         struct request_queue *q = shost->uspace_req_q;
144         struct request *rq = cmd->request;
145         struct scsi_tgt_cmd *tcmd = rq->end_io_data;
146         unsigned long flags;
147
148         kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
149
150         spin_lock_irqsave(q->queue_lock, flags);
151         __blk_put_request(q, rq);
152         spin_unlock_irqrestore(q->queue_lock, flags);
153
154         __scsi_put_command(shost, cmd, &shost->shost_gendev);
155 }
156 EXPORT_SYMBOL_GPL(scsi_host_put_command);
157
158 static void cmd_hashlist_del(struct scsi_cmnd *cmd)
159 {
160         struct request_queue *q = cmd->request->q;
161         struct scsi_tgt_queuedata *qdata = q->queuedata;
162         unsigned long flags;
163         struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
164
165         spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
166         list_del(&tcmd->hash_list);
167         spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
168 }
169
170 static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd)
171 {
172         blk_rq_unmap_user(tcmd->bio);
173 }
174
175 static void scsi_tgt_cmd_destroy(struct work_struct *work)
176 {
177         struct scsi_tgt_cmd *tcmd =
178                 container_of(work, struct scsi_tgt_cmd, work);
179         struct scsi_cmnd *cmd = tcmd->rq->special;
180
181         dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction,
182                 rq_data_dir(cmd->request));
183         scsi_unmap_user_pages(tcmd);
184         scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd);
185 }
186
187 static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd,
188                               u64 tag)
189 {
190         struct scsi_tgt_queuedata *qdata = rq->q->queuedata;
191         unsigned long flags;
192         struct list_head *head;
193
194         tcmd->tag = tag;
195         tcmd->bio = NULL;
196         INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy);
197         spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
198         head = &qdata->cmd_hash[cmd_hashfn(tag)];
199         list_add(&tcmd->hash_list, head);
200         spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
201 }
202
203 /*
204  * scsi_tgt_alloc_queue - setup queue used for message passing
205  * shost: scsi host
206  *
207  * This should be called by the LLD after host allocation.
208  * And will be released when the host is released.
209  */
210 int scsi_tgt_alloc_queue(struct Scsi_Host *shost)
211 {
212         struct scsi_tgt_queuedata *queuedata;
213         struct request_queue *q;
214         int err, i;
215
216         /*
217          * Do we need to send a netlink event or should uspace
218          * just respond to the hotplug event?
219          */
220         q = __scsi_alloc_queue(shost, NULL);
221         if (!q)
222                 return -ENOMEM;
223
224         queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL);
225         if (!queuedata) {
226                 err = -ENOMEM;
227                 goto cleanup_queue;
228         }
229         queuedata->shost = shost;
230         q->queuedata = queuedata;
231
232         /*
233          * this is a silly hack. We should probably just queue as many
234          * command as is recvd to userspace. uspace can then make
235          * sure we do not overload the HBA
236          */
237         q->nr_requests = shost->hostt->can_queue;
238         /*
239          * We currently only support software LLDs so this does
240          * not matter for now. Do we need this for the cards we support?
241          * If so we should make it a host template value.
242          */
243         blk_queue_dma_alignment(q, 0);
244         shost->uspace_req_q = q;
245
246         for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++)
247                 INIT_LIST_HEAD(&queuedata->cmd_hash[i]);
248         spin_lock_init(&queuedata->cmd_hash_lock);
249
250         return 0;
251
252 cleanup_queue:
253         blk_cleanup_queue(q);
254         return err;
255 }
256 EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue);
257
258 void scsi_tgt_free_queue(struct Scsi_Host *shost)
259 {
260         int i;
261         unsigned long flags;
262         struct request_queue *q = shost->uspace_req_q;
263         struct scsi_cmnd *cmd;
264         struct scsi_tgt_queuedata *qdata = q->queuedata;
265         struct scsi_tgt_cmd *tcmd, *n;
266         LIST_HEAD(cmds);
267
268         spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
269
270         for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) {
271                 list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i],
272                                          hash_list) {
273                         list_del(&tcmd->hash_list);
274                         list_add(&tcmd->hash_list, &cmds);
275                 }
276         }
277
278         spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
279
280         while (!list_empty(&cmds)) {
281                 tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list);
282                 list_del(&tcmd->hash_list);
283                 cmd = tcmd->rq->special;
284
285                 shost->hostt->eh_abort_handler(cmd);
286                 scsi_tgt_cmd_destroy(&tcmd->work);
287         }
288 }
289 EXPORT_SYMBOL_GPL(scsi_tgt_free_queue);
290
291 struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd)
292 {
293         struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata;
294         return queue->shost;
295 }
296 EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host);
297
298 /*
299  * scsi_tgt_queue_command - queue command for userspace processing
300  * @cmd:        scsi command
301  * @scsilun:    scsi lun
302  * @tag:        unique value to identify this command for tmf
303  */
304 int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun,
305                            u64 tag)
306 {
307         struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
308         int err;
309
310         init_scsi_tgt_cmd(cmd->request, tcmd, tag);
311         err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag);
312         if (err)
313                 cmd_hashlist_del(cmd);
314
315         return err;
316 }
317 EXPORT_SYMBOL_GPL(scsi_tgt_queue_command);
318
319 /*
320  * This is run from a interrpt handler normally and the unmap
321  * needs process context so we must queue
322  */
323 static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
324 {
325         struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
326
327         dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request));
328
329         scsi_tgt_uspace_send_status(cmd, tcmd->tag);
330
331         if (cmd->request_buffer)
332                 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
333
334         queue_work(scsi_tgtd, &tcmd->work);
335 }
336
337 static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd)
338 {
339         struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
340         int err;
341
342         dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request));
343
344         err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done);
345         switch (err) {
346         case SCSI_MLQUEUE_HOST_BUSY:
347         case SCSI_MLQUEUE_DEVICE_BUSY:
348                 return -EAGAIN;
349         }
350         return 0;
351 }
352
353 static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
354 {
355         struct request *rq = cmd->request;
356         int count;
357
358         cmd->use_sg = rq->nr_phys_segments;
359         cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask);
360         if (!cmd->request_buffer)
361                 return -ENOMEM;
362
363         cmd->request_bufflen = rq->data_len;
364
365         dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq));
366         count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer);
367         if (likely(count <= cmd->use_sg)) {
368                 cmd->use_sg = count;
369                 return 0;
370         }
371
372         eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg);
373         scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
374         return -EINVAL;
375 }
376
377 /* TODO: test this crap and replace bio_map_user with new interface maybe */
378 static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
379                                unsigned long uaddr, unsigned int len, int rw)
380 {
381         struct request_queue *q = cmd->request->q;
382         struct request *rq = cmd->request;
383         int err;
384
385         dprintk("%lx %u\n", uaddr, len);
386         err = blk_rq_map_user(q, rq, (void *)uaddr, len);
387         if (err) {
388                 /*
389                  * TODO: need to fixup sg_tablesize, max_segment_size,
390                  * max_sectors, etc for modern HW and software drivers
391                  * where this value is bogus.
392                  *
393                  * TODO2: we can alloc a reserve buffer of max size
394                  * we can handle and do the slow copy path for really large
395                  * IO.
396                  */
397                 eprintk("Could not handle request of size %u.\n", len);
398                 return err;
399         }
400
401         tcmd->bio = rq->bio;
402         err = scsi_tgt_init_cmd(cmd, GFP_KERNEL);
403         if (err)
404                 goto unmap_rq;
405
406         return 0;
407
408 unmap_rq:
409         scsi_unmap_user_pages(tcmd);
410         return err;
411 }
412
413 static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr,
414                                 unsigned len)
415 {
416         char __user *p = (char __user *) uaddr;
417
418         if (copy_from_user(cmd->sense_buffer, p,
419                            min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) {
420                 printk(KERN_ERR "Could not copy the sense buffer\n");
421                 return -EIO;
422         }
423         return 0;
424 }
425
426 static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
427 {
428         struct scsi_tgt_cmd *tcmd;
429         int err;
430
431         err = shost->hostt->eh_abort_handler(cmd);
432         if (err)
433                 eprintk("fail to abort %p\n", cmd);
434
435         tcmd = cmd->request->end_io_data;
436         scsi_tgt_cmd_destroy(&tcmd->work);
437         return err;
438 }
439
440 static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag)
441 {
442         struct scsi_tgt_queuedata *qdata = q->queuedata;
443         struct request *rq = NULL;
444         struct list_head *head;
445         struct scsi_tgt_cmd *tcmd;
446         unsigned long flags;
447
448         head = &qdata->cmd_hash[cmd_hashfn(tag)];
449         spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
450         list_for_each_entry(tcmd, head, hash_list) {
451                 if (tcmd->tag == tag) {
452                         rq = tcmd->rq;
453                         list_del(&tcmd->hash_list);
454                         break;
455                 }
456         }
457         spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
458
459         return rq;
460 }
461
462 int scsi_tgt_kspace_exec(int host_no, int result, u64 tag,
463                          unsigned long uaddr, u32 len, unsigned long sense_uaddr,
464                          u32 sense_len, u8 rw)
465 {
466         struct Scsi_Host *shost;
467         struct scsi_cmnd *cmd;
468         struct request *rq;
469         struct scsi_tgt_cmd *tcmd;
470         int err = 0;
471
472         dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag,
473                 result, len, uaddr, rw);
474
475         /* TODO: replace with a O(1) alg */
476         shost = scsi_host_lookup(host_no);
477         if (IS_ERR(shost)) {
478                 printk(KERN_ERR "Could not find host no %d\n", host_no);
479                 return -EINVAL;
480         }
481
482         if (!shost->uspace_req_q) {
483                 printk(KERN_ERR "Not target scsi host %d\n", host_no);
484                 goto done;
485         }
486
487         rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag);
488         if (!rq) {
489                 printk(KERN_ERR "Could not find tag %llu\n",
490                        (unsigned long long) tag);
491                 err = -EINVAL;
492                 goto done;
493         }
494         cmd = rq->special;
495
496         dprintk("cmd %p scb %x result %d len %d bufflen %u %lu %x\n",
497                 cmd, cmd->cmnd[0], result, len, cmd->request_bufflen,
498                 rq_data_dir(rq), cmd->cmnd[0]);
499
500         if (result == TASK_ABORTED) {
501                 scsi_tgt_abort_cmd(shost, cmd);
502                 goto done;
503         }
504         /*
505          * store the userspace values here, the working values are
506          * in the request_* values
507          */
508         tcmd = cmd->request->end_io_data;
509         cmd->result = result;
510
511         if (cmd->result == SAM_STAT_CHECK_CONDITION)
512                 scsi_tgt_copy_sense(cmd, sense_uaddr, sense_len);
513
514         if (len) {
515                 err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw);
516                 if (err) {
517                         /*
518                          * user-space daemon bugs or OOM
519                          * TODO: we can do better for OOM.
520                          */
521                         struct scsi_tgt_queuedata *qdata;
522                         struct list_head *head;
523                         unsigned long flags;
524
525                         eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n",
526                                 cmd, err, uaddr, len, rw);
527
528                         qdata = shost->uspace_req_q->queuedata;
529                         head = &qdata->cmd_hash[cmd_hashfn(tcmd->tag)];
530
531                         spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
532                         list_add(&tcmd->hash_list, head);
533                         spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
534
535                         goto done;
536                 }
537         }
538         err = scsi_tgt_transfer_response(cmd);
539 done:
540         scsi_host_put(shost);
541         return err;
542 }
543
544 int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag,
545                               struct scsi_lun *scsilun, void *data)
546 {
547         int err;
548
549         /* TODO: need to retry if this fails. */
550         err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function,
551                                             tag, scsilun, data);
552         if (err < 0)
553                 eprintk("The task management request lost!\n");
554         return err;
555 }
556 EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request);
557
558 int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result)
559 {
560         struct Scsi_Host *shost;
561         int err = -EINVAL;
562
563         dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid);
564
565         shost = scsi_host_lookup(host_no);
566         if (IS_ERR(shost)) {
567                 printk(KERN_ERR "Could not find host no %d\n", host_no);
568                 return err;
569         }
570
571         if (!shost->uspace_req_q) {
572                 printk(KERN_ERR "Not target scsi host %d\n", host_no);
573                 goto done;
574         }
575
576         err = shost->hostt->tsk_mgmt_response(mid, result);
577 done:
578         scsi_host_put(shost);
579         return err;
580 }
581
582 static int __init scsi_tgt_init(void)
583 {
584         int err;
585
586         scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd",
587                                                sizeof(struct scsi_tgt_cmd),
588                                                0, 0, NULL, NULL);
589         if (!scsi_tgt_cmd_cache)
590                 return -ENOMEM;
591
592         scsi_tgtd = create_workqueue("scsi_tgtd");
593         if (!scsi_tgtd) {
594                 err = -ENOMEM;
595                 goto free_kmemcache;
596         }
597
598         err = scsi_tgt_if_init();
599         if (err)
600                 goto destroy_wq;
601
602         return 0;
603
604 destroy_wq:
605         destroy_workqueue(scsi_tgtd);
606 free_kmemcache:
607         kmem_cache_destroy(scsi_tgt_cmd_cache);
608         return err;
609 }
610
611 static void __exit scsi_tgt_exit(void)
612 {
613         destroy_workqueue(scsi_tgtd);
614         scsi_tgt_if_exit();
615         kmem_cache_destroy(scsi_tgt_cmd_cache);
616 }
617
618 module_init(scsi_tgt_init);
619 module_exit(scsi_tgt_exit);
620
621 MODULE_DESCRIPTION("SCSI target core");
622 MODULE_LICENSE("GPL");