13d6392cfSJens Axboe /* 20c6a89baSFUJITA Tomonori * bsg.c - block layer implementation of the sg v4 interface 33d6392cfSJens Axboe * 43d6392cfSJens Axboe * Copyright (C) 2004 Jens Axboe <axboe@suse.de> SUSE Labs 53d6392cfSJens Axboe * Copyright (C) 2004 Peter M. Jones <pjones@redhat.com> 63d6392cfSJens Axboe * 73d6392cfSJens Axboe * This file is subject to the terms and conditions of the GNU General Public 83d6392cfSJens Axboe * License version 2. See the file "COPYING" in the main directory of this 93d6392cfSJens Axboe * archive for more details. 103d6392cfSJens Axboe * 113d6392cfSJens Axboe */ 123d6392cfSJens Axboe #include <linux/module.h> 133d6392cfSJens Axboe #include <linux/init.h> 143d6392cfSJens Axboe #include <linux/file.h> 153d6392cfSJens Axboe #include <linux/blkdev.h> 163d6392cfSJens Axboe #include <linux/poll.h> 173d6392cfSJens Axboe #include <linux/cdev.h> 183d6392cfSJens Axboe #include <linux/percpu.h> 193d6392cfSJens Axboe #include <linux/uio.h> 20598443a2SFUJITA Tomonori #include <linux/idr.h> 213d6392cfSJens Axboe #include <linux/bsg.h> 223d6392cfSJens Axboe 233d6392cfSJens Axboe #include <scsi/scsi.h> 243d6392cfSJens Axboe #include <scsi/scsi_ioctl.h> 253d6392cfSJens Axboe #include <scsi/scsi_cmnd.h> 264e2872d6SFUJITA Tomonori #include <scsi/scsi_device.h> 274e2872d6SFUJITA Tomonori #include <scsi/scsi_driver.h> 283d6392cfSJens Axboe #include <scsi/sg.h> 293d6392cfSJens Axboe 300ed081ceSFUJITA Tomonori #define BSG_DESCRIPTION "Block layer SCSI generic (bsg) driver" 310ed081ceSFUJITA Tomonori #define BSG_VERSION "0.4" 323d6392cfSJens Axboe 333d6392cfSJens Axboe struct bsg_device { 34165125e1SJens Axboe struct request_queue *queue; 353d6392cfSJens Axboe spinlock_t lock; 363d6392cfSJens Axboe struct list_head busy_list; 373d6392cfSJens Axboe struct list_head done_list; 383d6392cfSJens Axboe struct hlist_node dev_list; 393d6392cfSJens Axboe atomic_t ref_count; 403d6392cfSJens Axboe int minor; 413d6392cfSJens Axboe int queued_cmds; 423d6392cfSJens Axboe int done_cmds; 433d6392cfSJens Axboe wait_queue_head_t wq_done; 443d6392cfSJens Axboe wait_queue_head_t wq_free; 45d351af01SFUJITA Tomonori char name[BUS_ID_SIZE]; 463d6392cfSJens Axboe int max_queue; 473d6392cfSJens Axboe unsigned long flags; 483d6392cfSJens Axboe }; 493d6392cfSJens Axboe 503d6392cfSJens Axboe enum { 513d6392cfSJens Axboe BSG_F_BLOCK = 1, 523d6392cfSJens Axboe BSG_F_WRITE_PERM = 2, 533d6392cfSJens Axboe }; 543d6392cfSJens Axboe 555309cb38SJens Axboe #define BSG_DEFAULT_CMDS 64 56292b7f27SFUJITA Tomonori #define BSG_MAX_DEVS 32768 573d6392cfSJens Axboe 583d6392cfSJens Axboe #undef BSG_DEBUG 593d6392cfSJens Axboe 603d6392cfSJens Axboe #ifdef BSG_DEBUG 613d6392cfSJens Axboe #define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ##args) 623d6392cfSJens Axboe #else 633d6392cfSJens Axboe #define dprintk(fmt, args...) 643d6392cfSJens Axboe #endif 653d6392cfSJens Axboe 663d6392cfSJens Axboe static DEFINE_MUTEX(bsg_mutex); 67598443a2SFUJITA Tomonori static DEFINE_IDR(bsg_minor_idr); 683d6392cfSJens Axboe 6925fd1643SJens Axboe #define BSG_LIST_ARRAY_SIZE 8 7025fd1643SJens Axboe static struct hlist_head bsg_device_list[BSG_LIST_ARRAY_SIZE]; 713d6392cfSJens Axboe 723d6392cfSJens Axboe static struct class *bsg_class; 7346f6ef4aSJens Axboe static int bsg_major; 743d6392cfSJens Axboe 755309cb38SJens Axboe static struct kmem_cache *bsg_cmd_cachep; 765309cb38SJens Axboe 773d6392cfSJens Axboe /* 783d6392cfSJens Axboe * our internal command type 793d6392cfSJens Axboe */ 803d6392cfSJens Axboe struct bsg_command { 813d6392cfSJens Axboe struct bsg_device *bd; 823d6392cfSJens Axboe struct list_head list; 833d6392cfSJens Axboe struct request *rq; 843d6392cfSJens Axboe struct bio *bio; 852c9ecdf4SFUJITA Tomonori struct bio *bidi_bio; 863d6392cfSJens Axboe int err; 8770e36eceSFUJITA Tomonori struct sg_io_v4 hdr; 883d6392cfSJens Axboe char sense[SCSI_SENSE_BUFFERSIZE]; 893d6392cfSJens Axboe }; 903d6392cfSJens Axboe 913d6392cfSJens Axboe static void bsg_free_command(struct bsg_command *bc) 923d6392cfSJens Axboe { 933d6392cfSJens Axboe struct bsg_device *bd = bc->bd; 943d6392cfSJens Axboe unsigned long flags; 953d6392cfSJens Axboe 965309cb38SJens Axboe kmem_cache_free(bsg_cmd_cachep, bc); 973d6392cfSJens Axboe 983d6392cfSJens Axboe spin_lock_irqsave(&bd->lock, flags); 993d6392cfSJens Axboe bd->queued_cmds--; 1003d6392cfSJens Axboe spin_unlock_irqrestore(&bd->lock, flags); 1013d6392cfSJens Axboe 1023d6392cfSJens Axboe wake_up(&bd->wq_free); 1033d6392cfSJens Axboe } 1043d6392cfSJens Axboe 105e7d72173SFUJITA Tomonori static struct bsg_command *bsg_alloc_command(struct bsg_device *bd) 1063d6392cfSJens Axboe { 107e7d72173SFUJITA Tomonori struct bsg_command *bc = ERR_PTR(-EINVAL); 1083d6392cfSJens Axboe 1093d6392cfSJens Axboe spin_lock_irq(&bd->lock); 1103d6392cfSJens Axboe 1113d6392cfSJens Axboe if (bd->queued_cmds >= bd->max_queue) 1123d6392cfSJens Axboe goto out; 1133d6392cfSJens Axboe 1143d6392cfSJens Axboe bd->queued_cmds++; 1153d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1163d6392cfSJens Axboe 11725fd1643SJens Axboe bc = kmem_cache_zalloc(bsg_cmd_cachep, GFP_KERNEL); 1185309cb38SJens Axboe if (unlikely(!bc)) { 1195309cb38SJens Axboe spin_lock_irq(&bd->lock); 1207e75d730SFUJITA Tomonori bd->queued_cmds--; 121e7d72173SFUJITA Tomonori bc = ERR_PTR(-ENOMEM); 1227e75d730SFUJITA Tomonori goto out; 1235309cb38SJens Axboe } 1245309cb38SJens Axboe 1253d6392cfSJens Axboe bc->bd = bd; 1263d6392cfSJens Axboe INIT_LIST_HEAD(&bc->list); 1275309cb38SJens Axboe dprintk("%s: returning free cmd %p\n", bd->name, bc); 1283d6392cfSJens Axboe return bc; 1293d6392cfSJens Axboe out: 1303d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1313d6392cfSJens Axboe return bc; 1323d6392cfSJens Axboe } 1333d6392cfSJens Axboe 1341c1133e1SFUJITA Tomonori static inline struct hlist_head *bsg_dev_idx_hash(int index) 1353d6392cfSJens Axboe { 1361c1133e1SFUJITA Tomonori return &bsg_device_list[index & (BSG_LIST_ARRAY_SIZE - 1)]; 1373d6392cfSJens Axboe } 1383d6392cfSJens Axboe 13925fd1643SJens Axboe static int bsg_io_schedule(struct bsg_device *bd) 1403d6392cfSJens Axboe { 1413d6392cfSJens Axboe DEFINE_WAIT(wait); 1423d6392cfSJens Axboe int ret = 0; 1433d6392cfSJens Axboe 1443d6392cfSJens Axboe spin_lock_irq(&bd->lock); 1453d6392cfSJens Axboe 1463d6392cfSJens Axboe BUG_ON(bd->done_cmds > bd->queued_cmds); 1473d6392cfSJens Axboe 1483d6392cfSJens Axboe /* 1493d6392cfSJens Axboe * -ENOSPC or -ENODATA? I'm going for -ENODATA, meaning "I have no 1503d6392cfSJens Axboe * work to do", even though we return -ENOSPC after this same test 1513d6392cfSJens Axboe * during bsg_write() -- there, it means our buffer can't have more 1523d6392cfSJens Axboe * bsg_commands added to it, thus has no space left. 1533d6392cfSJens Axboe */ 1543d6392cfSJens Axboe if (bd->done_cmds == bd->queued_cmds) { 1553d6392cfSJens Axboe ret = -ENODATA; 1563d6392cfSJens Axboe goto unlock; 1573d6392cfSJens Axboe } 1583d6392cfSJens Axboe 1593d6392cfSJens Axboe if (!test_bit(BSG_F_BLOCK, &bd->flags)) { 1603d6392cfSJens Axboe ret = -EAGAIN; 1613d6392cfSJens Axboe goto unlock; 1623d6392cfSJens Axboe } 1633d6392cfSJens Axboe 16425fd1643SJens Axboe prepare_to_wait(&bd->wq_done, &wait, TASK_UNINTERRUPTIBLE); 1653d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1663d6392cfSJens Axboe io_schedule(); 1673d6392cfSJens Axboe finish_wait(&bd->wq_done, &wait); 1683d6392cfSJens Axboe 1693d6392cfSJens Axboe return ret; 1703d6392cfSJens Axboe unlock: 1713d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1723d6392cfSJens Axboe return ret; 1733d6392cfSJens Axboe } 1743d6392cfSJens Axboe 175165125e1SJens Axboe static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 17670e36eceSFUJITA Tomonori struct sg_io_v4 *hdr, int has_write_perm) 17770e36eceSFUJITA Tomonori { 17870e36eceSFUJITA Tomonori memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ 17970e36eceSFUJITA Tomonori 18070e36eceSFUJITA Tomonori if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, 18170e36eceSFUJITA Tomonori hdr->request_len)) 18270e36eceSFUJITA Tomonori return -EFAULT; 18315d10b61SFUJITA Tomonori 18415d10b61SFUJITA Tomonori if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 18570e36eceSFUJITA Tomonori if (blk_verify_command(rq->cmd, has_write_perm)) 18670e36eceSFUJITA Tomonori return -EPERM; 18715d10b61SFUJITA Tomonori } else if (!capable(CAP_SYS_RAWIO)) 18815d10b61SFUJITA Tomonori return -EPERM; 18970e36eceSFUJITA Tomonori 1903d6392cfSJens Axboe /* 19170e36eceSFUJITA Tomonori * fill in request structure 19270e36eceSFUJITA Tomonori */ 19370e36eceSFUJITA Tomonori rq->cmd_len = hdr->request_len; 19470e36eceSFUJITA Tomonori rq->cmd_type = REQ_TYPE_BLOCK_PC; 19570e36eceSFUJITA Tomonori 19670e36eceSFUJITA Tomonori rq->timeout = (hdr->timeout * HZ) / 1000; 19770e36eceSFUJITA Tomonori if (!rq->timeout) 19870e36eceSFUJITA Tomonori rq->timeout = q->sg_timeout; 19970e36eceSFUJITA Tomonori if (!rq->timeout) 20070e36eceSFUJITA Tomonori rq->timeout = BLK_DEFAULT_SG_TIMEOUT; 20170e36eceSFUJITA Tomonori 20270e36eceSFUJITA Tomonori return 0; 20370e36eceSFUJITA Tomonori } 20470e36eceSFUJITA Tomonori 20570e36eceSFUJITA Tomonori /* 20670e36eceSFUJITA Tomonori * Check if sg_io_v4 from user is allowed and valid 2073d6392cfSJens Axboe */ 2083d6392cfSJens Axboe static int 209165125e1SJens Axboe bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) 2103d6392cfSJens Axboe { 21115d10b61SFUJITA Tomonori int ret = 0; 21215d10b61SFUJITA Tomonori 21370e36eceSFUJITA Tomonori if (hdr->guard != 'Q') 2143d6392cfSJens Axboe return -EINVAL; 21570e36eceSFUJITA Tomonori if (hdr->request_len > BLK_MAX_CDB) 2163d6392cfSJens Axboe return -EINVAL; 21770e36eceSFUJITA Tomonori if (hdr->dout_xfer_len > (q->max_sectors << 9) || 21870e36eceSFUJITA Tomonori hdr->din_xfer_len > (q->max_sectors << 9)) 2193d6392cfSJens Axboe return -EIO; 2203d6392cfSJens Axboe 22115d10b61SFUJITA Tomonori switch (hdr->protocol) { 22215d10b61SFUJITA Tomonori case BSG_PROTOCOL_SCSI: 22315d10b61SFUJITA Tomonori switch (hdr->subprotocol) { 22415d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_CMD: 22515d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_TRANSPORT: 22615d10b61SFUJITA Tomonori break; 22715d10b61SFUJITA Tomonori default: 22815d10b61SFUJITA Tomonori ret = -EINVAL; 22915d10b61SFUJITA Tomonori } 23015d10b61SFUJITA Tomonori break; 23115d10b61SFUJITA Tomonori default: 23215d10b61SFUJITA Tomonori ret = -EINVAL; 23315d10b61SFUJITA Tomonori } 23470e36eceSFUJITA Tomonori 23570e36eceSFUJITA Tomonori *rw = hdr->dout_xfer_len ? WRITE : READ; 23615d10b61SFUJITA Tomonori return ret; 2373d6392cfSJens Axboe } 2383d6392cfSJens Axboe 2393d6392cfSJens Axboe /* 24070e36eceSFUJITA Tomonori * map sg_io_v4 to a request. 2413d6392cfSJens Axboe */ 2423d6392cfSJens Axboe static struct request * 24370e36eceSFUJITA Tomonori bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) 2443d6392cfSJens Axboe { 245165125e1SJens Axboe struct request_queue *q = bd->queue; 2462c9ecdf4SFUJITA Tomonori struct request *rq, *next_rq = NULL; 24725fd1643SJens Axboe int ret, rw; 24870e36eceSFUJITA Tomonori unsigned int dxfer_len; 24970e36eceSFUJITA Tomonori void *dxferp = NULL; 2503d6392cfSJens Axboe 25170e36eceSFUJITA Tomonori dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, 25270e36eceSFUJITA Tomonori hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, 25370e36eceSFUJITA Tomonori hdr->din_xfer_len); 2543d6392cfSJens Axboe 25570e36eceSFUJITA Tomonori ret = bsg_validate_sgv4_hdr(q, hdr, &rw); 2563d6392cfSJens Axboe if (ret) 2573d6392cfSJens Axboe return ERR_PTR(ret); 2583d6392cfSJens Axboe 2593d6392cfSJens Axboe /* 2603d6392cfSJens Axboe * map scatter-gather elements seperately and string them to request 2613d6392cfSJens Axboe */ 2623d6392cfSJens Axboe rq = blk_get_request(q, rw, GFP_KERNEL); 2632c9ecdf4SFUJITA Tomonori if (!rq) 2642c9ecdf4SFUJITA Tomonori return ERR_PTR(-ENOMEM); 26570e36eceSFUJITA Tomonori ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, 2663d6392cfSJens Axboe &bd->flags)); 2672c9ecdf4SFUJITA Tomonori if (ret) 2682c9ecdf4SFUJITA Tomonori goto out; 2692c9ecdf4SFUJITA Tomonori 2702c9ecdf4SFUJITA Tomonori if (rw == WRITE && hdr->din_xfer_len) { 2712c9ecdf4SFUJITA Tomonori if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) { 2722c9ecdf4SFUJITA Tomonori ret = -EOPNOTSUPP; 2732c9ecdf4SFUJITA Tomonori goto out; 2742c9ecdf4SFUJITA Tomonori } 2752c9ecdf4SFUJITA Tomonori 2762c9ecdf4SFUJITA Tomonori next_rq = blk_get_request(q, READ, GFP_KERNEL); 2772c9ecdf4SFUJITA Tomonori if (!next_rq) { 2782c9ecdf4SFUJITA Tomonori ret = -ENOMEM; 2792c9ecdf4SFUJITA Tomonori goto out; 2802c9ecdf4SFUJITA Tomonori } 2812c9ecdf4SFUJITA Tomonori rq->next_rq = next_rq; 2822c9ecdf4SFUJITA Tomonori 2832c9ecdf4SFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 2842c9ecdf4SFUJITA Tomonori ret = blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len); 2852c9ecdf4SFUJITA Tomonori if (ret) 2862c9ecdf4SFUJITA Tomonori goto out; 2873d6392cfSJens Axboe } 2883d6392cfSJens Axboe 28970e36eceSFUJITA Tomonori if (hdr->dout_xfer_len) { 29070e36eceSFUJITA Tomonori dxfer_len = hdr->dout_xfer_len; 29170e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->dout_xferp; 29270e36eceSFUJITA Tomonori } else if (hdr->din_xfer_len) { 29370e36eceSFUJITA Tomonori dxfer_len = hdr->din_xfer_len; 29470e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 29570e36eceSFUJITA Tomonori } else 29670e36eceSFUJITA Tomonori dxfer_len = 0; 2973d6392cfSJens Axboe 29870e36eceSFUJITA Tomonori if (dxfer_len) { 29970e36eceSFUJITA Tomonori ret = blk_rq_map_user(q, rq, dxferp, dxfer_len); 3002c9ecdf4SFUJITA Tomonori if (ret) 3012c9ecdf4SFUJITA Tomonori goto out; 3023d6392cfSJens Axboe } 3033d6392cfSJens Axboe return rq; 3042c9ecdf4SFUJITA Tomonori out: 3052c9ecdf4SFUJITA Tomonori blk_put_request(rq); 3062c9ecdf4SFUJITA Tomonori if (next_rq) { 3072c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(next_rq->bio); 3082c9ecdf4SFUJITA Tomonori blk_put_request(next_rq); 3092c9ecdf4SFUJITA Tomonori } 3102c9ecdf4SFUJITA Tomonori return ERR_PTR(ret); 3113d6392cfSJens Axboe } 3123d6392cfSJens Axboe 3133d6392cfSJens Axboe /* 3143d6392cfSJens Axboe * async completion call-back from the block layer, when scsi/ide/whatever 3153d6392cfSJens Axboe * calls end_that_request_last() on a request 3163d6392cfSJens Axboe */ 3173d6392cfSJens Axboe static void bsg_rq_end_io(struct request *rq, int uptodate) 3183d6392cfSJens Axboe { 3193d6392cfSJens Axboe struct bsg_command *bc = rq->end_io_data; 3203d6392cfSJens Axboe struct bsg_device *bd = bc->bd; 3213d6392cfSJens Axboe unsigned long flags; 3223d6392cfSJens Axboe 3235309cb38SJens Axboe dprintk("%s: finished rq %p bc %p, bio %p stat %d\n", 3245309cb38SJens Axboe bd->name, rq, bc, bc->bio, uptodate); 3253d6392cfSJens Axboe 3263d6392cfSJens Axboe bc->hdr.duration = jiffies_to_msecs(jiffies - bc->hdr.duration); 3273d6392cfSJens Axboe 3283d6392cfSJens Axboe spin_lock_irqsave(&bd->lock, flags); 32925fd1643SJens Axboe list_move_tail(&bc->list, &bd->done_list); 33025fd1643SJens Axboe bd->done_cmds++; 3313d6392cfSJens Axboe spin_unlock_irqrestore(&bd->lock, flags); 33225fd1643SJens Axboe 33325fd1643SJens Axboe wake_up(&bd->wq_done); 3343d6392cfSJens Axboe } 3353d6392cfSJens Axboe 3363d6392cfSJens Axboe /* 3373d6392cfSJens Axboe * do final setup of a 'bc' and submit the matching 'rq' to the block 3383d6392cfSJens Axboe * layer for io 3393d6392cfSJens Axboe */ 340165125e1SJens Axboe static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, 3413d6392cfSJens Axboe struct bsg_command *bc, struct request *rq) 3423d6392cfSJens Axboe { 3433d6392cfSJens Axboe rq->sense = bc->sense; 3443d6392cfSJens Axboe rq->sense_len = 0; 3453d6392cfSJens Axboe 3463d6392cfSJens Axboe /* 3473d6392cfSJens Axboe * add bc command to busy queue and submit rq for io 3483d6392cfSJens Axboe */ 3493d6392cfSJens Axboe bc->rq = rq; 3503d6392cfSJens Axboe bc->bio = rq->bio; 3512c9ecdf4SFUJITA Tomonori if (rq->next_rq) 3522c9ecdf4SFUJITA Tomonori bc->bidi_bio = rq->next_rq->bio; 3533d6392cfSJens Axboe bc->hdr.duration = jiffies; 3543d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3553d6392cfSJens Axboe list_add_tail(&bc->list, &bd->busy_list); 3563d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3573d6392cfSJens Axboe 3583d6392cfSJens Axboe dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); 3593d6392cfSJens Axboe 3603d6392cfSJens Axboe rq->end_io_data = bc; 361d351af01SFUJITA Tomonori blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io); 3623d6392cfSJens Axboe } 3633d6392cfSJens Axboe 36425fd1643SJens Axboe static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) 3653d6392cfSJens Axboe { 3663d6392cfSJens Axboe struct bsg_command *bc = NULL; 3673d6392cfSJens Axboe 3683d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3693d6392cfSJens Axboe if (bd->done_cmds) { 37025fd1643SJens Axboe bc = list_entry(bd->done_list.next, struct bsg_command, list); 37125fd1643SJens Axboe list_del(&bc->list); 37225fd1643SJens Axboe bd->done_cmds--; 3733d6392cfSJens Axboe } 3743d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3753d6392cfSJens Axboe 3763d6392cfSJens Axboe return bc; 3773d6392cfSJens Axboe } 3783d6392cfSJens Axboe 3793d6392cfSJens Axboe /* 3803d6392cfSJens Axboe * Get a finished command from the done list 3813d6392cfSJens Axboe */ 382e7d72173SFUJITA Tomonori static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd) 3833d6392cfSJens Axboe { 3843d6392cfSJens Axboe struct bsg_command *bc; 3853d6392cfSJens Axboe int ret; 3863d6392cfSJens Axboe 3873d6392cfSJens Axboe do { 3883d6392cfSJens Axboe bc = bsg_next_done_cmd(bd); 3893d6392cfSJens Axboe if (bc) 3903d6392cfSJens Axboe break; 3913d6392cfSJens Axboe 392e7d72173SFUJITA Tomonori if (!test_bit(BSG_F_BLOCK, &bd->flags)) { 393e7d72173SFUJITA Tomonori bc = ERR_PTR(-EAGAIN); 394e7d72173SFUJITA Tomonori break; 395e7d72173SFUJITA Tomonori } 396e7d72173SFUJITA Tomonori 397e7d72173SFUJITA Tomonori ret = wait_event_interruptible(bd->wq_done, bd->done_cmds); 3983d6392cfSJens Axboe if (ret) { 399e7d72173SFUJITA Tomonori bc = ERR_PTR(-ERESTARTSYS); 4003d6392cfSJens Axboe break; 4013d6392cfSJens Axboe } 4023d6392cfSJens Axboe } while (1); 4033d6392cfSJens Axboe 4043d6392cfSJens Axboe dprintk("%s: returning done %p\n", bd->name, bc); 4053d6392cfSJens Axboe 4063d6392cfSJens Axboe return bc; 4073d6392cfSJens Axboe } 4083d6392cfSJens Axboe 40970e36eceSFUJITA Tomonori static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, 4102c9ecdf4SFUJITA Tomonori struct bio *bio, struct bio *bidi_bio) 41170e36eceSFUJITA Tomonori { 41270e36eceSFUJITA Tomonori int ret = 0; 41370e36eceSFUJITA Tomonori 41470e36eceSFUJITA Tomonori dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); 41570e36eceSFUJITA Tomonori /* 41670e36eceSFUJITA Tomonori * fill in all the output members 41770e36eceSFUJITA Tomonori */ 41870e36eceSFUJITA Tomonori hdr->device_status = status_byte(rq->errors); 41970e36eceSFUJITA Tomonori hdr->transport_status = host_byte(rq->errors); 42070e36eceSFUJITA Tomonori hdr->driver_status = driver_byte(rq->errors); 42170e36eceSFUJITA Tomonori hdr->info = 0; 42270e36eceSFUJITA Tomonori if (hdr->device_status || hdr->transport_status || hdr->driver_status) 42370e36eceSFUJITA Tomonori hdr->info |= SG_INFO_CHECK; 42470e36eceSFUJITA Tomonori hdr->response_len = 0; 42570e36eceSFUJITA Tomonori 42670e36eceSFUJITA Tomonori if (rq->sense_len && hdr->response) { 42725fd1643SJens Axboe int len = min_t(unsigned int, hdr->max_response_len, 42870e36eceSFUJITA Tomonori rq->sense_len); 42970e36eceSFUJITA Tomonori 43070e36eceSFUJITA Tomonori ret = copy_to_user((void*)(unsigned long)hdr->response, 43170e36eceSFUJITA Tomonori rq->sense, len); 43270e36eceSFUJITA Tomonori if (!ret) 43370e36eceSFUJITA Tomonori hdr->response_len = len; 43470e36eceSFUJITA Tomonori else 43570e36eceSFUJITA Tomonori ret = -EFAULT; 43670e36eceSFUJITA Tomonori } 43770e36eceSFUJITA Tomonori 4382c9ecdf4SFUJITA Tomonori if (rq->next_rq) { 4390c6a89baSFUJITA Tomonori hdr->dout_resid = rq->data_len; 4400c6a89baSFUJITA Tomonori hdr->din_resid = rq->next_rq->data_len; 4412c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(bidi_bio); 4422c9ecdf4SFUJITA Tomonori blk_put_request(rq->next_rq); 4430c6a89baSFUJITA Tomonori } else if (rq_data_dir(rq) == READ) 4440c6a89baSFUJITA Tomonori hdr->din_resid = rq->data_len; 4450c6a89baSFUJITA Tomonori else 4460c6a89baSFUJITA Tomonori hdr->dout_resid = rq->data_len; 4472c9ecdf4SFUJITA Tomonori 44870e36eceSFUJITA Tomonori blk_rq_unmap_user(bio); 44970e36eceSFUJITA Tomonori blk_put_request(rq); 45070e36eceSFUJITA Tomonori 45170e36eceSFUJITA Tomonori return ret; 45270e36eceSFUJITA Tomonori } 45370e36eceSFUJITA Tomonori 4543d6392cfSJens Axboe static int bsg_complete_all_commands(struct bsg_device *bd) 4553d6392cfSJens Axboe { 4563d6392cfSJens Axboe struct bsg_command *bc; 4573d6392cfSJens Axboe int ret, tret; 4583d6392cfSJens Axboe 4593d6392cfSJens Axboe dprintk("%s: entered\n", bd->name); 4603d6392cfSJens Axboe 4613d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 4623d6392cfSJens Axboe 4633d6392cfSJens Axboe /* 4643d6392cfSJens Axboe * wait for all commands to complete 4653d6392cfSJens Axboe */ 4663d6392cfSJens Axboe ret = 0; 4673d6392cfSJens Axboe do { 46825fd1643SJens Axboe ret = bsg_io_schedule(bd); 4693d6392cfSJens Axboe /* 4703d6392cfSJens Axboe * look for -ENODATA specifically -- we'll sometimes get 4713d6392cfSJens Axboe * -ERESTARTSYS when we've taken a signal, but we can't 4723d6392cfSJens Axboe * return until we're done freeing the queue, so ignore 4733d6392cfSJens Axboe * it. The signal will get handled when we're done freeing 4743d6392cfSJens Axboe * the bsg_device. 4753d6392cfSJens Axboe */ 4763d6392cfSJens Axboe } while (ret != -ENODATA); 4773d6392cfSJens Axboe 4783d6392cfSJens Axboe /* 4793d6392cfSJens Axboe * discard done commands 4803d6392cfSJens Axboe */ 4813d6392cfSJens Axboe ret = 0; 4823d6392cfSJens Axboe do { 483e7d72173SFUJITA Tomonori spin_lock_irq(&bd->lock); 484e7d72173SFUJITA Tomonori if (!bd->queued_cmds) { 485e7d72173SFUJITA Tomonori spin_unlock_irq(&bd->lock); 4863d6392cfSJens Axboe break; 4873d6392cfSJens Axboe } 488efba1a31SFUJITA Tomonori spin_unlock_irq(&bd->lock); 4893d6392cfSJens Axboe 490e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 491e7d72173SFUJITA Tomonori if (IS_ERR(bc)) 492e7d72173SFUJITA Tomonori break; 493e7d72173SFUJITA Tomonori 4942c9ecdf4SFUJITA Tomonori tret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 4952c9ecdf4SFUJITA Tomonori bc->bidi_bio); 4963d6392cfSJens Axboe if (!ret) 4973d6392cfSJens Axboe ret = tret; 4983d6392cfSJens Axboe 4993d6392cfSJens Axboe bsg_free_command(bc); 5003d6392cfSJens Axboe } while (1); 5013d6392cfSJens Axboe 5023d6392cfSJens Axboe return ret; 5033d6392cfSJens Axboe } 5043d6392cfSJens Axboe 50525fd1643SJens Axboe static int 506e7d72173SFUJITA Tomonori __bsg_read(char __user *buf, size_t count, struct bsg_device *bd, 507e7d72173SFUJITA Tomonori const struct iovec *iov, ssize_t *bytes_read) 5083d6392cfSJens Axboe { 5093d6392cfSJens Axboe struct bsg_command *bc; 5103d6392cfSJens Axboe int nr_commands, ret; 5113d6392cfSJens Axboe 51270e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 5133d6392cfSJens Axboe return -EINVAL; 5143d6392cfSJens Axboe 5153d6392cfSJens Axboe ret = 0; 51670e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 5173d6392cfSJens Axboe while (nr_commands) { 518e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 5193d6392cfSJens Axboe if (IS_ERR(bc)) { 5203d6392cfSJens Axboe ret = PTR_ERR(bc); 5213d6392cfSJens Axboe break; 5223d6392cfSJens Axboe } 5233d6392cfSJens Axboe 5243d6392cfSJens Axboe /* 5253d6392cfSJens Axboe * this is the only case where we need to copy data back 5263d6392cfSJens Axboe * after completing the request. so do that here, 5273d6392cfSJens Axboe * bsg_complete_work() cannot do that for us 5283d6392cfSJens Axboe */ 5292c9ecdf4SFUJITA Tomonori ret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 5302c9ecdf4SFUJITA Tomonori bc->bidi_bio); 5313d6392cfSJens Axboe 53225fd1643SJens Axboe if (copy_to_user(buf, &bc->hdr, sizeof(bc->hdr))) 5333d6392cfSJens Axboe ret = -EFAULT; 5343d6392cfSJens Axboe 5353d6392cfSJens Axboe bsg_free_command(bc); 5363d6392cfSJens Axboe 5373d6392cfSJens Axboe if (ret) 5383d6392cfSJens Axboe break; 5393d6392cfSJens Axboe 54070e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 54170e36eceSFUJITA Tomonori *bytes_read += sizeof(struct sg_io_v4); 5423d6392cfSJens Axboe nr_commands--; 5433d6392cfSJens Axboe } 5443d6392cfSJens Axboe 5453d6392cfSJens Axboe return ret; 5463d6392cfSJens Axboe } 5473d6392cfSJens Axboe 5483d6392cfSJens Axboe static inline void bsg_set_block(struct bsg_device *bd, struct file *file) 5493d6392cfSJens Axboe { 5503d6392cfSJens Axboe if (file->f_flags & O_NONBLOCK) 5513d6392cfSJens Axboe clear_bit(BSG_F_BLOCK, &bd->flags); 5523d6392cfSJens Axboe else 5533d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 5543d6392cfSJens Axboe } 5553d6392cfSJens Axboe 5563d6392cfSJens Axboe static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) 5573d6392cfSJens Axboe { 5583d6392cfSJens Axboe if (file->f_mode & FMODE_WRITE) 5593d6392cfSJens Axboe set_bit(BSG_F_WRITE_PERM, &bd->flags); 5603d6392cfSJens Axboe else 5613d6392cfSJens Axboe clear_bit(BSG_F_WRITE_PERM, &bd->flags); 5623d6392cfSJens Axboe } 5633d6392cfSJens Axboe 56425fd1643SJens Axboe /* 56525fd1643SJens Axboe * Check if the error is a "real" error that we should return. 56625fd1643SJens Axboe */ 5673d6392cfSJens Axboe static inline int err_block_err(int ret) 5683d6392cfSJens Axboe { 5693d6392cfSJens Axboe if (ret && ret != -ENOSPC && ret != -ENODATA && ret != -EAGAIN) 5703d6392cfSJens Axboe return 1; 5713d6392cfSJens Axboe 5723d6392cfSJens Axboe return 0; 5733d6392cfSJens Axboe } 5743d6392cfSJens Axboe 5753d6392cfSJens Axboe static ssize_t 5763d6392cfSJens Axboe bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 5773d6392cfSJens Axboe { 5783d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 5793d6392cfSJens Axboe int ret; 5803d6392cfSJens Axboe ssize_t bytes_read; 5813d6392cfSJens Axboe 5829e69fbb5SFUJITA Tomonori dprintk("%s: read %Zd bytes\n", bd->name, count); 5833d6392cfSJens Axboe 5843d6392cfSJens Axboe bsg_set_block(bd, file); 5853d6392cfSJens Axboe bytes_read = 0; 586e7d72173SFUJITA Tomonori ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 5873d6392cfSJens Axboe *ppos = bytes_read; 5883d6392cfSJens Axboe 5893d6392cfSJens Axboe if (!bytes_read || (bytes_read && err_block_err(ret))) 5903d6392cfSJens Axboe bytes_read = ret; 5913d6392cfSJens Axboe 5923d6392cfSJens Axboe return bytes_read; 5933d6392cfSJens Axboe } 5943d6392cfSJens Axboe 59525fd1643SJens Axboe static int __bsg_write(struct bsg_device *bd, const char __user *buf, 59625fd1643SJens Axboe size_t count, ssize_t *bytes_written) 5973d6392cfSJens Axboe { 5983d6392cfSJens Axboe struct bsg_command *bc; 5993d6392cfSJens Axboe struct request *rq; 6003d6392cfSJens Axboe int ret, nr_commands; 6013d6392cfSJens Axboe 60270e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 6033d6392cfSJens Axboe return -EINVAL; 6043d6392cfSJens Axboe 60570e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 6063d6392cfSJens Axboe rq = NULL; 6073d6392cfSJens Axboe bc = NULL; 6083d6392cfSJens Axboe ret = 0; 6093d6392cfSJens Axboe while (nr_commands) { 610165125e1SJens Axboe struct request_queue *q = bd->queue; 6113d6392cfSJens Axboe 612e7d72173SFUJITA Tomonori bc = bsg_alloc_command(bd); 6133d6392cfSJens Axboe if (IS_ERR(bc)) { 6143d6392cfSJens Axboe ret = PTR_ERR(bc); 6153d6392cfSJens Axboe bc = NULL; 6163d6392cfSJens Axboe break; 6173d6392cfSJens Axboe } 6183d6392cfSJens Axboe 6193d6392cfSJens Axboe if (copy_from_user(&bc->hdr, buf, sizeof(bc->hdr))) { 6203d6392cfSJens Axboe ret = -EFAULT; 6213d6392cfSJens Axboe break; 6223d6392cfSJens Axboe } 6233d6392cfSJens Axboe 6243d6392cfSJens Axboe /* 6253d6392cfSJens Axboe * get a request, fill in the blanks, and add to request queue 6263d6392cfSJens Axboe */ 62770e36eceSFUJITA Tomonori rq = bsg_map_hdr(bd, &bc->hdr); 6283d6392cfSJens Axboe if (IS_ERR(rq)) { 6293d6392cfSJens Axboe ret = PTR_ERR(rq); 6303d6392cfSJens Axboe rq = NULL; 6313d6392cfSJens Axboe break; 6323d6392cfSJens Axboe } 6333d6392cfSJens Axboe 6343d6392cfSJens Axboe bsg_add_command(bd, q, bc, rq); 6353d6392cfSJens Axboe bc = NULL; 6363d6392cfSJens Axboe rq = NULL; 6373d6392cfSJens Axboe nr_commands--; 63870e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 63925fd1643SJens Axboe *bytes_written += sizeof(struct sg_io_v4); 6403d6392cfSJens Axboe } 6413d6392cfSJens Axboe 6423d6392cfSJens Axboe if (bc) 6433d6392cfSJens Axboe bsg_free_command(bc); 6443d6392cfSJens Axboe 6453d6392cfSJens Axboe return ret; 6463d6392cfSJens Axboe } 6473d6392cfSJens Axboe 6483d6392cfSJens Axboe static ssize_t 6493d6392cfSJens Axboe bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 6503d6392cfSJens Axboe { 6513d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 65225fd1643SJens Axboe ssize_t bytes_written; 6533d6392cfSJens Axboe int ret; 6543d6392cfSJens Axboe 6559e69fbb5SFUJITA Tomonori dprintk("%s: write %Zd bytes\n", bd->name, count); 6563d6392cfSJens Axboe 6573d6392cfSJens Axboe bsg_set_block(bd, file); 6583d6392cfSJens Axboe bsg_set_write_perm(bd, file); 6593d6392cfSJens Axboe 66025fd1643SJens Axboe bytes_written = 0; 66125fd1643SJens Axboe ret = __bsg_write(bd, buf, count, &bytes_written); 66225fd1643SJens Axboe *ppos = bytes_written; 6633d6392cfSJens Axboe 6643d6392cfSJens Axboe /* 6653d6392cfSJens Axboe * return bytes written on non-fatal errors 6663d6392cfSJens Axboe */ 66725fd1643SJens Axboe if (!bytes_written || (bytes_written && err_block_err(ret))) 66825fd1643SJens Axboe bytes_written = ret; 6693d6392cfSJens Axboe 67025fd1643SJens Axboe dprintk("%s: returning %Zd\n", bd->name, bytes_written); 67125fd1643SJens Axboe return bytes_written; 6723d6392cfSJens Axboe } 6733d6392cfSJens Axboe 6743d6392cfSJens Axboe static struct bsg_device *bsg_alloc_device(void) 6753d6392cfSJens Axboe { 6763d6392cfSJens Axboe struct bsg_device *bd; 6773d6392cfSJens Axboe 6783d6392cfSJens Axboe bd = kzalloc(sizeof(struct bsg_device), GFP_KERNEL); 6793d6392cfSJens Axboe if (unlikely(!bd)) 6803d6392cfSJens Axboe return NULL; 6813d6392cfSJens Axboe 6823d6392cfSJens Axboe spin_lock_init(&bd->lock); 6833d6392cfSJens Axboe 6845309cb38SJens Axboe bd->max_queue = BSG_DEFAULT_CMDS; 6853d6392cfSJens Axboe 6863d6392cfSJens Axboe INIT_LIST_HEAD(&bd->busy_list); 6873d6392cfSJens Axboe INIT_LIST_HEAD(&bd->done_list); 6883d6392cfSJens Axboe INIT_HLIST_NODE(&bd->dev_list); 6893d6392cfSJens Axboe 6903d6392cfSJens Axboe init_waitqueue_head(&bd->wq_free); 6913d6392cfSJens Axboe init_waitqueue_head(&bd->wq_done); 6923d6392cfSJens Axboe return bd; 6933d6392cfSJens Axboe } 6943d6392cfSJens Axboe 6953d6392cfSJens Axboe static int bsg_put_device(struct bsg_device *bd) 6963d6392cfSJens Axboe { 6973d6392cfSJens Axboe int ret = 0; 6983d6392cfSJens Axboe 6993d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7003d6392cfSJens Axboe 7013d6392cfSJens Axboe if (!atomic_dec_and_test(&bd->ref_count)) 7023d6392cfSJens Axboe goto out; 7033d6392cfSJens Axboe 7043d6392cfSJens Axboe dprintk("%s: tearing down\n", bd->name); 7053d6392cfSJens Axboe 7063d6392cfSJens Axboe /* 7073d6392cfSJens Axboe * close can always block 7083d6392cfSJens Axboe */ 7093d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 7103d6392cfSJens Axboe 7113d6392cfSJens Axboe /* 7123d6392cfSJens Axboe * correct error detection baddies here again. it's the responsibility 7133d6392cfSJens Axboe * of the app to properly reap commands before close() if it wants 7143d6392cfSJens Axboe * fool-proof error detection 7153d6392cfSJens Axboe */ 7163d6392cfSJens Axboe ret = bsg_complete_all_commands(bd); 7173d6392cfSJens Axboe 7183d6392cfSJens Axboe blk_put_queue(bd->queue); 7193d6392cfSJens Axboe hlist_del(&bd->dev_list); 7205309cb38SJens Axboe kfree(bd); 7213d6392cfSJens Axboe out: 7223d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7233d6392cfSJens Axboe return ret; 7243d6392cfSJens Axboe } 7253d6392cfSJens Axboe 7263d6392cfSJens Axboe static struct bsg_device *bsg_add_device(struct inode *inode, 727d351af01SFUJITA Tomonori struct request_queue *rq, 7283d6392cfSJens Axboe struct file *file) 7293d6392cfSJens Axboe { 73025fd1643SJens Axboe struct bsg_device *bd; 7313d6392cfSJens Axboe #ifdef BSG_DEBUG 7323d6392cfSJens Axboe unsigned char buf[32]; 7333d6392cfSJens Axboe #endif 7343d6392cfSJens Axboe 7353d6392cfSJens Axboe bd = bsg_alloc_device(); 7363d6392cfSJens Axboe if (!bd) 7373d6392cfSJens Axboe return ERR_PTR(-ENOMEM); 7383d6392cfSJens Axboe 739d351af01SFUJITA Tomonori bd->queue = rq; 740d351af01SFUJITA Tomonori kobject_get(&rq->kobj); 7413d6392cfSJens Axboe bsg_set_block(bd, file); 7423d6392cfSJens Axboe 7433d6392cfSJens Axboe atomic_set(&bd->ref_count, 1); 7443d6392cfSJens Axboe bd->minor = iminor(inode); 7453d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7461c1133e1SFUJITA Tomonori hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor)); 7473d6392cfSJens Axboe 748d351af01SFUJITA Tomonori strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); 7493d6392cfSJens Axboe dprintk("bound to <%s>, max queue %d\n", 7509e69fbb5SFUJITA Tomonori format_dev_t(buf, inode->i_rdev), bd->max_queue); 7513d6392cfSJens Axboe 7523d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7533d6392cfSJens Axboe return bd; 7543d6392cfSJens Axboe } 7553d6392cfSJens Axboe 7563d6392cfSJens Axboe static struct bsg_device *__bsg_get_device(int minor) 7573d6392cfSJens Axboe { 7583d6392cfSJens Axboe struct bsg_device *bd = NULL; 7593d6392cfSJens Axboe struct hlist_node *entry; 7603d6392cfSJens Axboe 7613d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7623d6392cfSJens Axboe 7631c1133e1SFUJITA Tomonori hlist_for_each(entry, bsg_dev_idx_hash(minor)) { 7643d6392cfSJens Axboe bd = hlist_entry(entry, struct bsg_device, dev_list); 7653d6392cfSJens Axboe if (bd->minor == minor) { 7663d6392cfSJens Axboe atomic_inc(&bd->ref_count); 7673d6392cfSJens Axboe break; 7683d6392cfSJens Axboe } 7693d6392cfSJens Axboe 7703d6392cfSJens Axboe bd = NULL; 7713d6392cfSJens Axboe } 7723d6392cfSJens Axboe 7733d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7743d6392cfSJens Axboe return bd; 7753d6392cfSJens Axboe } 7763d6392cfSJens Axboe 7773d6392cfSJens Axboe static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) 7783d6392cfSJens Axboe { 779598443a2SFUJITA Tomonori struct bsg_device *bd; 780598443a2SFUJITA Tomonori struct bsg_class_device *bcd; 7813d6392cfSJens Axboe 782598443a2SFUJITA Tomonori bd = __bsg_get_device(iminor(inode)); 7833d6392cfSJens Axboe if (bd) 7843d6392cfSJens Axboe return bd; 7853d6392cfSJens Axboe 7863d6392cfSJens Axboe /* 7873d6392cfSJens Axboe * find the class device 7883d6392cfSJens Axboe */ 7893d6392cfSJens Axboe mutex_lock(&bsg_mutex); 790598443a2SFUJITA Tomonori bcd = idr_find(&bsg_minor_idr, iminor(inode)); 7913d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7923d6392cfSJens Axboe 7933d6392cfSJens Axboe if (!bcd) 7943d6392cfSJens Axboe return ERR_PTR(-ENODEV); 7953d6392cfSJens Axboe 796d351af01SFUJITA Tomonori return bsg_add_device(inode, bcd->queue, file); 7973d6392cfSJens Axboe } 7983d6392cfSJens Axboe 7993d6392cfSJens Axboe static int bsg_open(struct inode *inode, struct file *file) 8003d6392cfSJens Axboe { 8013d6392cfSJens Axboe struct bsg_device *bd = bsg_get_device(inode, file); 8023d6392cfSJens Axboe 8033d6392cfSJens Axboe if (IS_ERR(bd)) 8043d6392cfSJens Axboe return PTR_ERR(bd); 8053d6392cfSJens Axboe 8063d6392cfSJens Axboe file->private_data = bd; 8073d6392cfSJens Axboe return 0; 8083d6392cfSJens Axboe } 8093d6392cfSJens Axboe 8103d6392cfSJens Axboe static int bsg_release(struct inode *inode, struct file *file) 8113d6392cfSJens Axboe { 8123d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8133d6392cfSJens Axboe 8143d6392cfSJens Axboe file->private_data = NULL; 8153d6392cfSJens Axboe return bsg_put_device(bd); 8163d6392cfSJens Axboe } 8173d6392cfSJens Axboe 8183d6392cfSJens Axboe static unsigned int bsg_poll(struct file *file, poll_table *wait) 8193d6392cfSJens Axboe { 8203d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8213d6392cfSJens Axboe unsigned int mask = 0; 8223d6392cfSJens Axboe 8233d6392cfSJens Axboe poll_wait(file, &bd->wq_done, wait); 8243d6392cfSJens Axboe poll_wait(file, &bd->wq_free, wait); 8253d6392cfSJens Axboe 8263d6392cfSJens Axboe spin_lock_irq(&bd->lock); 8273d6392cfSJens Axboe if (!list_empty(&bd->done_list)) 8283d6392cfSJens Axboe mask |= POLLIN | POLLRDNORM; 8293d6392cfSJens Axboe if (bd->queued_cmds >= bd->max_queue) 8303d6392cfSJens Axboe mask |= POLLOUT; 8313d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 8323d6392cfSJens Axboe 8333d6392cfSJens Axboe return mask; 8343d6392cfSJens Axboe } 8353d6392cfSJens Axboe 83625fd1643SJens Axboe static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 8373d6392cfSJens Axboe { 8383d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8393d6392cfSJens Axboe int __user *uarg = (int __user *) arg; 8403d6392cfSJens Axboe 8413d6392cfSJens Axboe switch (cmd) { 8423d6392cfSJens Axboe /* 8433d6392cfSJens Axboe * our own ioctls 8443d6392cfSJens Axboe */ 8453d6392cfSJens Axboe case SG_GET_COMMAND_Q: 8463d6392cfSJens Axboe return put_user(bd->max_queue, uarg); 8473d6392cfSJens Axboe case SG_SET_COMMAND_Q: { 8483d6392cfSJens Axboe int queue; 8493d6392cfSJens Axboe 8503d6392cfSJens Axboe if (get_user(queue, uarg)) 8513d6392cfSJens Axboe return -EFAULT; 8525309cb38SJens Axboe if (queue < 1) 8533d6392cfSJens Axboe return -EINVAL; 8543d6392cfSJens Axboe 8555309cb38SJens Axboe spin_lock_irq(&bd->lock); 8563d6392cfSJens Axboe bd->max_queue = queue; 8575309cb38SJens Axboe spin_unlock_irq(&bd->lock); 8583d6392cfSJens Axboe return 0; 8593d6392cfSJens Axboe } 8603d6392cfSJens Axboe 8613d6392cfSJens Axboe /* 8623d6392cfSJens Axboe * SCSI/sg ioctls 8633d6392cfSJens Axboe */ 8643d6392cfSJens Axboe case SG_GET_VERSION_NUM: 8653d6392cfSJens Axboe case SCSI_IOCTL_GET_IDLUN: 8663d6392cfSJens Axboe case SCSI_IOCTL_GET_BUS_NUMBER: 8673d6392cfSJens Axboe case SG_SET_TIMEOUT: 8683d6392cfSJens Axboe case SG_GET_TIMEOUT: 8693d6392cfSJens Axboe case SG_GET_RESERVED_SIZE: 8703d6392cfSJens Axboe case SG_SET_RESERVED_SIZE: 8713d6392cfSJens Axboe case SG_EMULATED_HOST: 8723d6392cfSJens Axboe case SCSI_IOCTL_SEND_COMMAND: { 8733d6392cfSJens Axboe void __user *uarg = (void __user *) arg; 874d351af01SFUJITA Tomonori return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); 8753d6392cfSJens Axboe } 87610e8855bSFUJITA Tomonori case SG_IO: { 87710e8855bSFUJITA Tomonori struct request *rq; 8782c9ecdf4SFUJITA Tomonori struct bio *bio, *bidi_bio = NULL; 87910e8855bSFUJITA Tomonori struct sg_io_v4 hdr; 88010e8855bSFUJITA Tomonori 88110e8855bSFUJITA Tomonori if (copy_from_user(&hdr, uarg, sizeof(hdr))) 88210e8855bSFUJITA Tomonori return -EFAULT; 88310e8855bSFUJITA Tomonori 88410e8855bSFUJITA Tomonori rq = bsg_map_hdr(bd, &hdr); 88510e8855bSFUJITA Tomonori if (IS_ERR(rq)) 88610e8855bSFUJITA Tomonori return PTR_ERR(rq); 88710e8855bSFUJITA Tomonori 88810e8855bSFUJITA Tomonori bio = rq->bio; 8892c9ecdf4SFUJITA Tomonori if (rq->next_rq) 8902c9ecdf4SFUJITA Tomonori bidi_bio = rq->next_rq->bio; 891d351af01SFUJITA Tomonori blk_execute_rq(bd->queue, NULL, rq, 0); 8922c9ecdf4SFUJITA Tomonori blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); 89310e8855bSFUJITA Tomonori 89410e8855bSFUJITA Tomonori if (copy_to_user(uarg, &hdr, sizeof(hdr))) 89510e8855bSFUJITA Tomonori return -EFAULT; 896b711afa6SJens Axboe 89710e8855bSFUJITA Tomonori return 0; 89810e8855bSFUJITA Tomonori } 8993d6392cfSJens Axboe /* 9003d6392cfSJens Axboe * block device ioctls 9013d6392cfSJens Axboe */ 9023d6392cfSJens Axboe default: 9033d6392cfSJens Axboe #if 0 9043d6392cfSJens Axboe return ioctl_by_bdev(bd->bdev, cmd, arg); 9053d6392cfSJens Axboe #else 9063d6392cfSJens Axboe return -ENOTTY; 9073d6392cfSJens Axboe #endif 9083d6392cfSJens Axboe } 9093d6392cfSJens Axboe } 9103d6392cfSJens Axboe 9113d6392cfSJens Axboe static struct file_operations bsg_fops = { 9123d6392cfSJens Axboe .read = bsg_read, 9133d6392cfSJens Axboe .write = bsg_write, 9143d6392cfSJens Axboe .poll = bsg_poll, 9153d6392cfSJens Axboe .open = bsg_open, 9163d6392cfSJens Axboe .release = bsg_release, 91725fd1643SJens Axboe .unlocked_ioctl = bsg_ioctl, 9183d6392cfSJens Axboe .owner = THIS_MODULE, 9193d6392cfSJens Axboe }; 9203d6392cfSJens Axboe 921d351af01SFUJITA Tomonori void bsg_unregister_queue(struct request_queue *q) 9223d6392cfSJens Axboe { 923d351af01SFUJITA Tomonori struct bsg_class_device *bcd = &q->bsg_dev; 9243d6392cfSJens Axboe 925df468820SFUJITA Tomonori if (!bcd->class_dev) 926df468820SFUJITA Tomonori return; 9273d6392cfSJens Axboe 9283d6392cfSJens Axboe mutex_lock(&bsg_mutex); 929598443a2SFUJITA Tomonori idr_remove(&bsg_minor_idr, bcd->minor); 930d351af01SFUJITA Tomonori sysfs_remove_link(&q->kobj, "bsg"); 93139dca558SJames Bottomley class_device_unregister(bcd->class_dev); 93239dca558SJames Bottomley put_device(bcd->dev); 9333d6392cfSJens Axboe bcd->class_dev = NULL; 93439dca558SJames Bottomley bcd->dev = NULL; 9353d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 9363d6392cfSJens Axboe } 9374cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_unregister_queue); 9383d6392cfSJens Axboe 93939dca558SJames Bottomley int bsg_register_queue(struct request_queue *q, struct device *gdev, 94039dca558SJames Bottomley const char *name) 9413d6392cfSJens Axboe { 942598443a2SFUJITA Tomonori struct bsg_class_device *bcd; 9433d6392cfSJens Axboe dev_t dev; 944598443a2SFUJITA Tomonori int ret, minor; 9454e2872d6SFUJITA Tomonori struct class_device *class_dev = NULL; 94639dca558SJames Bottomley const char *devname; 94739dca558SJames Bottomley 94839dca558SJames Bottomley if (name) 94939dca558SJames Bottomley devname = name; 95039dca558SJames Bottomley else 95139dca558SJames Bottomley devname = gdev->bus_id; 9523d6392cfSJens Axboe 9533d6392cfSJens Axboe /* 9543d6392cfSJens Axboe * we need a proper transport to send commands, not a stacked device 9553d6392cfSJens Axboe */ 9563d6392cfSJens Axboe if (!q->request_fn) 9573d6392cfSJens Axboe return 0; 9583d6392cfSJens Axboe 959d351af01SFUJITA Tomonori bcd = &q->bsg_dev; 9603d6392cfSJens Axboe memset(bcd, 0, sizeof(*bcd)); 9613d6392cfSJens Axboe 9623d6392cfSJens Axboe mutex_lock(&bsg_mutex); 963598443a2SFUJITA Tomonori 964598443a2SFUJITA Tomonori ret = idr_pre_get(&bsg_minor_idr, GFP_KERNEL); 965598443a2SFUJITA Tomonori if (!ret) { 966598443a2SFUJITA Tomonori ret = -ENOMEM; 967598443a2SFUJITA Tomonori goto unlock; 968598443a2SFUJITA Tomonori } 969598443a2SFUJITA Tomonori 970598443a2SFUJITA Tomonori ret = idr_get_new(&bsg_minor_idr, bcd, &minor); 971598443a2SFUJITA Tomonori if (ret < 0) 972598443a2SFUJITA Tomonori goto unlock; 973598443a2SFUJITA Tomonori 974598443a2SFUJITA Tomonori if (minor >= BSG_MAX_DEVS) { 975292b7f27SFUJITA Tomonori printk(KERN_ERR "bsg: too many bsg devices\n"); 976598443a2SFUJITA Tomonori ret = -EINVAL; 977598443a2SFUJITA Tomonori goto remove_idr; 978292b7f27SFUJITA Tomonori } 979292b7f27SFUJITA Tomonori 980598443a2SFUJITA Tomonori bcd->minor = minor; 981d351af01SFUJITA Tomonori bcd->queue = q; 98239dca558SJames Bottomley bcd->dev = get_device(gdev); 98346f6ef4aSJens Axboe dev = MKDEV(bsg_major, bcd->minor); 98439dca558SJames Bottomley class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s", 98539dca558SJames Bottomley devname); 9864e2872d6SFUJITA Tomonori if (IS_ERR(class_dev)) { 9874e2872d6SFUJITA Tomonori ret = PTR_ERR(class_dev); 988598443a2SFUJITA Tomonori goto put_dev; 9894e2872d6SFUJITA Tomonori } 9904e2872d6SFUJITA Tomonori bcd->class_dev = class_dev; 9914e2872d6SFUJITA Tomonori 992abce891aSLinus Torvalds if (q->kobj.sd) { 9934e2872d6SFUJITA Tomonori ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); 9944e2872d6SFUJITA Tomonori if (ret) 995598443a2SFUJITA Tomonori goto unregister_class_dev; 9964e2872d6SFUJITA Tomonori } 9974e2872d6SFUJITA Tomonori 9983d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 9993d6392cfSJens Axboe return 0; 10006826ee4fSJames Bottomley 1001598443a2SFUJITA Tomonori unregister_class_dev: 10026826ee4fSJames Bottomley class_device_unregister(class_dev); 1003598443a2SFUJITA Tomonori put_dev: 100439dca558SJames Bottomley put_device(gdev); 1005598443a2SFUJITA Tomonori remove_idr: 1006598443a2SFUJITA Tomonori idr_remove(&bsg_minor_idr, minor); 1007598443a2SFUJITA Tomonori unlock: 1008264a0472SJens Axboe mutex_unlock(&bsg_mutex); 10094e2872d6SFUJITA Tomonori return ret; 10103d6392cfSJens Axboe } 10114cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_register_queue); 10123d6392cfSJens Axboe 1013*7e7654a9SGreg Kroah-Hartman static struct cdev bsg_cdev; 1014292b7f27SFUJITA Tomonori 10153d6392cfSJens Axboe static int __init bsg_init(void) 10163d6392cfSJens Axboe { 10173d6392cfSJens Axboe int ret, i; 101846f6ef4aSJens Axboe dev_t devid; 10193d6392cfSJens Axboe 10205309cb38SJens Axboe bsg_cmd_cachep = kmem_cache_create("bsg_cmd", 102120c2df83SPaul Mundt sizeof(struct bsg_command), 0, 0, NULL); 10225309cb38SJens Axboe if (!bsg_cmd_cachep) { 10235309cb38SJens Axboe printk(KERN_ERR "bsg: failed creating slab cache\n"); 10245309cb38SJens Axboe return -ENOMEM; 10255309cb38SJens Axboe } 10265309cb38SJens Axboe 102725fd1643SJens Axboe for (i = 0; i < BSG_LIST_ARRAY_SIZE; i++) 10283d6392cfSJens Axboe INIT_HLIST_HEAD(&bsg_device_list[i]); 10293d6392cfSJens Axboe 10303d6392cfSJens Axboe bsg_class = class_create(THIS_MODULE, "bsg"); 10315309cb38SJens Axboe if (IS_ERR(bsg_class)) { 10329b9f770cSFUJITA Tomonori ret = PTR_ERR(bsg_class); 10339b9f770cSFUJITA Tomonori goto destroy_kmemcache; 10345309cb38SJens Axboe } 10353d6392cfSJens Axboe 103646f6ef4aSJens Axboe ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg"); 10379b9f770cSFUJITA Tomonori if (ret) 10389b9f770cSFUJITA Tomonori goto destroy_bsg_class; 10393d6392cfSJens Axboe 104046f6ef4aSJens Axboe bsg_major = MAJOR(devid); 104146f6ef4aSJens Axboe 1042292b7f27SFUJITA Tomonori cdev_init(&bsg_cdev, &bsg_fops); 104346f6ef4aSJens Axboe ret = cdev_add(&bsg_cdev, MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10449b9f770cSFUJITA Tomonori if (ret) 10459b9f770cSFUJITA Tomonori goto unregister_chrdev; 1046292b7f27SFUJITA Tomonori 10470ed081ceSFUJITA Tomonori printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION 10480ed081ceSFUJITA Tomonori " loaded (major %d)\n", bsg_major); 10493d6392cfSJens Axboe return 0; 10509b9f770cSFUJITA Tomonori unregister_chrdev: 10519b9f770cSFUJITA Tomonori unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10529b9f770cSFUJITA Tomonori destroy_bsg_class: 10539b9f770cSFUJITA Tomonori class_destroy(bsg_class); 10549b9f770cSFUJITA Tomonori destroy_kmemcache: 10559b9f770cSFUJITA Tomonori kmem_cache_destroy(bsg_cmd_cachep); 10569b9f770cSFUJITA Tomonori return ret; 10573d6392cfSJens Axboe } 10583d6392cfSJens Axboe 10593d6392cfSJens Axboe MODULE_AUTHOR("Jens Axboe"); 10600ed081ceSFUJITA Tomonori MODULE_DESCRIPTION(BSG_DESCRIPTION); 10613d6392cfSJens Axboe MODULE_LICENSE("GPL"); 10623d6392cfSJens Axboe 10634e2872d6SFUJITA Tomonori device_initcall(bsg_init); 1064