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> 22*75bd2ef1SJonathan Corbet #include <linux/smp_lock.h> 233d6392cfSJens Axboe 243d6392cfSJens Axboe #include <scsi/scsi.h> 253d6392cfSJens Axboe #include <scsi/scsi_ioctl.h> 263d6392cfSJens Axboe #include <scsi/scsi_cmnd.h> 274e2872d6SFUJITA Tomonori #include <scsi/scsi_device.h> 284e2872d6SFUJITA Tomonori #include <scsi/scsi_driver.h> 293d6392cfSJens Axboe #include <scsi/sg.h> 303d6392cfSJens Axboe 310ed081ceSFUJITA Tomonori #define BSG_DESCRIPTION "Block layer SCSI generic (bsg) driver" 320ed081ceSFUJITA Tomonori #define BSG_VERSION "0.4" 333d6392cfSJens Axboe 343d6392cfSJens Axboe struct bsg_device { 35165125e1SJens Axboe struct request_queue *queue; 363d6392cfSJens Axboe spinlock_t lock; 373d6392cfSJens Axboe struct list_head busy_list; 383d6392cfSJens Axboe struct list_head done_list; 393d6392cfSJens Axboe struct hlist_node dev_list; 403d6392cfSJens Axboe atomic_t ref_count; 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 6124c03d47SHarvey Harrison #define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ##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 { 1789f5de6b1SFUJITA Tomonori if (hdr->request_len > BLK_MAX_CDB) { 1799f5de6b1SFUJITA Tomonori rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 1809f5de6b1SFUJITA Tomonori if (!rq->cmd) 1819f5de6b1SFUJITA Tomonori return -ENOMEM; 1829f5de6b1SFUJITA Tomonori } 18370e36eceSFUJITA Tomonori 18470e36eceSFUJITA Tomonori if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, 18570e36eceSFUJITA Tomonori hdr->request_len)) 18670e36eceSFUJITA Tomonori return -EFAULT; 18715d10b61SFUJITA Tomonori 18815d10b61SFUJITA Tomonori if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 18970e36eceSFUJITA Tomonori if (blk_verify_command(rq->cmd, has_write_perm)) 19070e36eceSFUJITA Tomonori return -EPERM; 19115d10b61SFUJITA Tomonori } else if (!capable(CAP_SYS_RAWIO)) 19215d10b61SFUJITA Tomonori return -EPERM; 19370e36eceSFUJITA Tomonori 1943d6392cfSJens Axboe /* 19570e36eceSFUJITA Tomonori * fill in request structure 19670e36eceSFUJITA Tomonori */ 19770e36eceSFUJITA Tomonori rq->cmd_len = hdr->request_len; 19870e36eceSFUJITA Tomonori rq->cmd_type = REQ_TYPE_BLOCK_PC; 19970e36eceSFUJITA Tomonori 20070e36eceSFUJITA Tomonori rq->timeout = (hdr->timeout * HZ) / 1000; 20170e36eceSFUJITA Tomonori if (!rq->timeout) 20270e36eceSFUJITA Tomonori rq->timeout = q->sg_timeout; 20370e36eceSFUJITA Tomonori if (!rq->timeout) 20470e36eceSFUJITA Tomonori rq->timeout = BLK_DEFAULT_SG_TIMEOUT; 20570e36eceSFUJITA Tomonori 20670e36eceSFUJITA Tomonori return 0; 20770e36eceSFUJITA Tomonori } 20870e36eceSFUJITA Tomonori 20970e36eceSFUJITA Tomonori /* 21070e36eceSFUJITA Tomonori * Check if sg_io_v4 from user is allowed and valid 2113d6392cfSJens Axboe */ 2123d6392cfSJens Axboe static int 213165125e1SJens Axboe bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) 2143d6392cfSJens Axboe { 21515d10b61SFUJITA Tomonori int ret = 0; 21615d10b61SFUJITA Tomonori 21770e36eceSFUJITA Tomonori if (hdr->guard != 'Q') 2183d6392cfSJens Axboe return -EINVAL; 21970e36eceSFUJITA Tomonori if (hdr->dout_xfer_len > (q->max_sectors << 9) || 22070e36eceSFUJITA Tomonori hdr->din_xfer_len > (q->max_sectors << 9)) 2213d6392cfSJens Axboe return -EIO; 2223d6392cfSJens Axboe 22315d10b61SFUJITA Tomonori switch (hdr->protocol) { 22415d10b61SFUJITA Tomonori case BSG_PROTOCOL_SCSI: 22515d10b61SFUJITA Tomonori switch (hdr->subprotocol) { 22615d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_CMD: 22715d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_TRANSPORT: 22815d10b61SFUJITA Tomonori break; 22915d10b61SFUJITA Tomonori default: 23015d10b61SFUJITA Tomonori ret = -EINVAL; 23115d10b61SFUJITA Tomonori } 23215d10b61SFUJITA Tomonori break; 23315d10b61SFUJITA Tomonori default: 23415d10b61SFUJITA Tomonori ret = -EINVAL; 23515d10b61SFUJITA Tomonori } 23670e36eceSFUJITA Tomonori 23770e36eceSFUJITA Tomonori *rw = hdr->dout_xfer_len ? WRITE : READ; 23815d10b61SFUJITA Tomonori return ret; 2393d6392cfSJens Axboe } 2403d6392cfSJens Axboe 2413d6392cfSJens Axboe /* 24270e36eceSFUJITA Tomonori * map sg_io_v4 to a request. 2433d6392cfSJens Axboe */ 2443d6392cfSJens Axboe static struct request * 24570e36eceSFUJITA Tomonori bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) 2463d6392cfSJens Axboe { 247165125e1SJens Axboe struct request_queue *q = bd->queue; 2482c9ecdf4SFUJITA Tomonori struct request *rq, *next_rq = NULL; 24925fd1643SJens Axboe int ret, rw; 25070e36eceSFUJITA Tomonori unsigned int dxfer_len; 25170e36eceSFUJITA Tomonori void *dxferp = NULL; 2523d6392cfSJens Axboe 25370e36eceSFUJITA Tomonori dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, 25470e36eceSFUJITA Tomonori hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, 25570e36eceSFUJITA Tomonori hdr->din_xfer_len); 2563d6392cfSJens Axboe 25770e36eceSFUJITA Tomonori ret = bsg_validate_sgv4_hdr(q, hdr, &rw); 2583d6392cfSJens Axboe if (ret) 2593d6392cfSJens Axboe return ERR_PTR(ret); 2603d6392cfSJens Axboe 2613d6392cfSJens Axboe /* 2623d6392cfSJens Axboe * map scatter-gather elements seperately and string them to request 2633d6392cfSJens Axboe */ 2643d6392cfSJens Axboe rq = blk_get_request(q, rw, GFP_KERNEL); 2652c9ecdf4SFUJITA Tomonori if (!rq) 2662c9ecdf4SFUJITA Tomonori return ERR_PTR(-ENOMEM); 26770e36eceSFUJITA Tomonori ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, 2683d6392cfSJens Axboe &bd->flags)); 2692c9ecdf4SFUJITA Tomonori if (ret) 2702c9ecdf4SFUJITA Tomonori goto out; 2712c9ecdf4SFUJITA Tomonori 2722c9ecdf4SFUJITA Tomonori if (rw == WRITE && hdr->din_xfer_len) { 2732c9ecdf4SFUJITA Tomonori if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) { 2742c9ecdf4SFUJITA Tomonori ret = -EOPNOTSUPP; 2752c9ecdf4SFUJITA Tomonori goto out; 2762c9ecdf4SFUJITA Tomonori } 2772c9ecdf4SFUJITA Tomonori 2782c9ecdf4SFUJITA Tomonori next_rq = blk_get_request(q, READ, GFP_KERNEL); 2792c9ecdf4SFUJITA Tomonori if (!next_rq) { 2802c9ecdf4SFUJITA Tomonori ret = -ENOMEM; 2812c9ecdf4SFUJITA Tomonori goto out; 2822c9ecdf4SFUJITA Tomonori } 2832c9ecdf4SFUJITA Tomonori rq->next_rq = next_rq; 28440f62028SJames Bottomley next_rq->cmd_type = rq->cmd_type; 2852c9ecdf4SFUJITA Tomonori 2862c9ecdf4SFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 2872c9ecdf4SFUJITA Tomonori ret = blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len); 2882c9ecdf4SFUJITA Tomonori if (ret) 2892c9ecdf4SFUJITA Tomonori goto out; 2903d6392cfSJens Axboe } 2913d6392cfSJens Axboe 29270e36eceSFUJITA Tomonori if (hdr->dout_xfer_len) { 29370e36eceSFUJITA Tomonori dxfer_len = hdr->dout_xfer_len; 29470e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->dout_xferp; 29570e36eceSFUJITA Tomonori } else if (hdr->din_xfer_len) { 29670e36eceSFUJITA Tomonori dxfer_len = hdr->din_xfer_len; 29770e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 29870e36eceSFUJITA Tomonori } else 29970e36eceSFUJITA Tomonori dxfer_len = 0; 3003d6392cfSJens Axboe 30170e36eceSFUJITA Tomonori if (dxfer_len) { 30270e36eceSFUJITA Tomonori ret = blk_rq_map_user(q, rq, dxferp, dxfer_len); 3032c9ecdf4SFUJITA Tomonori if (ret) 3042c9ecdf4SFUJITA Tomonori goto out; 3053d6392cfSJens Axboe } 3063d6392cfSJens Axboe return rq; 3072c9ecdf4SFUJITA Tomonori out: 3089f5de6b1SFUJITA Tomonori if (rq->cmd != rq->__cmd) 3099f5de6b1SFUJITA Tomonori kfree(rq->cmd); 3102c9ecdf4SFUJITA Tomonori blk_put_request(rq); 3112c9ecdf4SFUJITA Tomonori if (next_rq) { 3122c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(next_rq->bio); 3132c9ecdf4SFUJITA Tomonori blk_put_request(next_rq); 3142c9ecdf4SFUJITA Tomonori } 3152c9ecdf4SFUJITA Tomonori return ERR_PTR(ret); 3163d6392cfSJens Axboe } 3173d6392cfSJens Axboe 3183d6392cfSJens Axboe /* 3193d6392cfSJens Axboe * async completion call-back from the block layer, when scsi/ide/whatever 3203d6392cfSJens Axboe * calls end_that_request_last() on a request 3213d6392cfSJens Axboe */ 3223d6392cfSJens Axboe static void bsg_rq_end_io(struct request *rq, int uptodate) 3233d6392cfSJens Axboe { 3243d6392cfSJens Axboe struct bsg_command *bc = rq->end_io_data; 3253d6392cfSJens Axboe struct bsg_device *bd = bc->bd; 3263d6392cfSJens Axboe unsigned long flags; 3273d6392cfSJens Axboe 3285309cb38SJens Axboe dprintk("%s: finished rq %p bc %p, bio %p stat %d\n", 3295309cb38SJens Axboe bd->name, rq, bc, bc->bio, uptodate); 3303d6392cfSJens Axboe 3313d6392cfSJens Axboe bc->hdr.duration = jiffies_to_msecs(jiffies - bc->hdr.duration); 3323d6392cfSJens Axboe 3333d6392cfSJens Axboe spin_lock_irqsave(&bd->lock, flags); 33425fd1643SJens Axboe list_move_tail(&bc->list, &bd->done_list); 33525fd1643SJens Axboe bd->done_cmds++; 3363d6392cfSJens Axboe spin_unlock_irqrestore(&bd->lock, flags); 33725fd1643SJens Axboe 33825fd1643SJens Axboe wake_up(&bd->wq_done); 3393d6392cfSJens Axboe } 3403d6392cfSJens Axboe 3413d6392cfSJens Axboe /* 3423d6392cfSJens Axboe * do final setup of a 'bc' and submit the matching 'rq' to the block 3433d6392cfSJens Axboe * layer for io 3443d6392cfSJens Axboe */ 345165125e1SJens Axboe static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, 3463d6392cfSJens Axboe struct bsg_command *bc, struct request *rq) 3473d6392cfSJens Axboe { 3483d6392cfSJens Axboe rq->sense = bc->sense; 3493d6392cfSJens Axboe rq->sense_len = 0; 3503d6392cfSJens Axboe 3513d6392cfSJens Axboe /* 3523d6392cfSJens Axboe * add bc command to busy queue and submit rq for io 3533d6392cfSJens Axboe */ 3543d6392cfSJens Axboe bc->rq = rq; 3553d6392cfSJens Axboe bc->bio = rq->bio; 3562c9ecdf4SFUJITA Tomonori if (rq->next_rq) 3572c9ecdf4SFUJITA Tomonori bc->bidi_bio = rq->next_rq->bio; 3583d6392cfSJens Axboe bc->hdr.duration = jiffies; 3593d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3603d6392cfSJens Axboe list_add_tail(&bc->list, &bd->busy_list); 3613d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3623d6392cfSJens Axboe 3633d6392cfSJens Axboe dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); 3643d6392cfSJens Axboe 3653d6392cfSJens Axboe rq->end_io_data = bc; 366d351af01SFUJITA Tomonori blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io); 3673d6392cfSJens Axboe } 3683d6392cfSJens Axboe 36925fd1643SJens Axboe static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) 3703d6392cfSJens Axboe { 3713d6392cfSJens Axboe struct bsg_command *bc = NULL; 3723d6392cfSJens Axboe 3733d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3743d6392cfSJens Axboe if (bd->done_cmds) { 37543ac9e62SFUJITA Tomonori bc = list_first_entry(&bd->done_list, struct bsg_command, list); 37625fd1643SJens Axboe list_del(&bc->list); 37725fd1643SJens Axboe bd->done_cmds--; 3783d6392cfSJens Axboe } 3793d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3803d6392cfSJens Axboe 3813d6392cfSJens Axboe return bc; 3823d6392cfSJens Axboe } 3833d6392cfSJens Axboe 3843d6392cfSJens Axboe /* 3853d6392cfSJens Axboe * Get a finished command from the done list 3863d6392cfSJens Axboe */ 387e7d72173SFUJITA Tomonori static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd) 3883d6392cfSJens Axboe { 3893d6392cfSJens Axboe struct bsg_command *bc; 3903d6392cfSJens Axboe int ret; 3913d6392cfSJens Axboe 3923d6392cfSJens Axboe do { 3933d6392cfSJens Axboe bc = bsg_next_done_cmd(bd); 3943d6392cfSJens Axboe if (bc) 3953d6392cfSJens Axboe break; 3963d6392cfSJens Axboe 397e7d72173SFUJITA Tomonori if (!test_bit(BSG_F_BLOCK, &bd->flags)) { 398e7d72173SFUJITA Tomonori bc = ERR_PTR(-EAGAIN); 399e7d72173SFUJITA Tomonori break; 400e7d72173SFUJITA Tomonori } 401e7d72173SFUJITA Tomonori 402e7d72173SFUJITA Tomonori ret = wait_event_interruptible(bd->wq_done, bd->done_cmds); 4033d6392cfSJens Axboe if (ret) { 404e7d72173SFUJITA Tomonori bc = ERR_PTR(-ERESTARTSYS); 4053d6392cfSJens Axboe break; 4063d6392cfSJens Axboe } 4073d6392cfSJens Axboe } while (1); 4083d6392cfSJens Axboe 4093d6392cfSJens Axboe dprintk("%s: returning done %p\n", bd->name, bc); 4103d6392cfSJens Axboe 4113d6392cfSJens Axboe return bc; 4123d6392cfSJens Axboe } 4133d6392cfSJens Axboe 41470e36eceSFUJITA Tomonori static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, 4152c9ecdf4SFUJITA Tomonori struct bio *bio, struct bio *bidi_bio) 41670e36eceSFUJITA Tomonori { 41770e36eceSFUJITA Tomonori int ret = 0; 41870e36eceSFUJITA Tomonori 41970e36eceSFUJITA Tomonori dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); 42070e36eceSFUJITA Tomonori /* 42170e36eceSFUJITA Tomonori * fill in all the output members 42270e36eceSFUJITA Tomonori */ 42370e36eceSFUJITA Tomonori hdr->device_status = status_byte(rq->errors); 42470e36eceSFUJITA Tomonori hdr->transport_status = host_byte(rq->errors); 42570e36eceSFUJITA Tomonori hdr->driver_status = driver_byte(rq->errors); 42670e36eceSFUJITA Tomonori hdr->info = 0; 42770e36eceSFUJITA Tomonori if (hdr->device_status || hdr->transport_status || hdr->driver_status) 42870e36eceSFUJITA Tomonori hdr->info |= SG_INFO_CHECK; 42970e36eceSFUJITA Tomonori hdr->response_len = 0; 43070e36eceSFUJITA Tomonori 43170e36eceSFUJITA Tomonori if (rq->sense_len && hdr->response) { 43225fd1643SJens Axboe int len = min_t(unsigned int, hdr->max_response_len, 43370e36eceSFUJITA Tomonori rq->sense_len); 43470e36eceSFUJITA Tomonori 43570e36eceSFUJITA Tomonori ret = copy_to_user((void*)(unsigned long)hdr->response, 43670e36eceSFUJITA Tomonori rq->sense, len); 43770e36eceSFUJITA Tomonori if (!ret) 43870e36eceSFUJITA Tomonori hdr->response_len = len; 43970e36eceSFUJITA Tomonori else 44070e36eceSFUJITA Tomonori ret = -EFAULT; 44170e36eceSFUJITA Tomonori } 44270e36eceSFUJITA Tomonori 4432c9ecdf4SFUJITA Tomonori if (rq->next_rq) { 4447a85f889SFUJITA Tomonori hdr->dout_resid = rq->data_len; 4457a85f889SFUJITA Tomonori hdr->din_resid = rq->next_rq->data_len; 4462c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(bidi_bio); 4472c9ecdf4SFUJITA Tomonori blk_put_request(rq->next_rq); 4480c6a89baSFUJITA Tomonori } else if (rq_data_dir(rq) == READ) 4497a85f889SFUJITA Tomonori hdr->din_resid = rq->data_len; 4500c6a89baSFUJITA Tomonori else 4517a85f889SFUJITA Tomonori hdr->dout_resid = rq->data_len; 4522c9ecdf4SFUJITA Tomonori 4532d507a01SJames Bottomley /* 4542d507a01SJames Bottomley * If the request generated a negative error number, return it 4552d507a01SJames Bottomley * (providing we aren't already returning an error); if it's 4562d507a01SJames Bottomley * just a protocol response (i.e. non negative), that gets 4572d507a01SJames Bottomley * processed above. 4582d507a01SJames Bottomley */ 4592d507a01SJames Bottomley if (!ret && rq->errors < 0) 4602d507a01SJames Bottomley ret = rq->errors; 4612d507a01SJames Bottomley 46270e36eceSFUJITA Tomonori blk_rq_unmap_user(bio); 4639f5de6b1SFUJITA Tomonori if (rq->cmd != rq->__cmd) 4649f5de6b1SFUJITA Tomonori kfree(rq->cmd); 46570e36eceSFUJITA Tomonori blk_put_request(rq); 46670e36eceSFUJITA Tomonori 46770e36eceSFUJITA Tomonori return ret; 46870e36eceSFUJITA Tomonori } 46970e36eceSFUJITA Tomonori 4703d6392cfSJens Axboe static int bsg_complete_all_commands(struct bsg_device *bd) 4713d6392cfSJens Axboe { 4723d6392cfSJens Axboe struct bsg_command *bc; 4733d6392cfSJens Axboe int ret, tret; 4743d6392cfSJens Axboe 4753d6392cfSJens Axboe dprintk("%s: entered\n", bd->name); 4763d6392cfSJens Axboe 4773d6392cfSJens Axboe /* 4783d6392cfSJens Axboe * wait for all commands to complete 4793d6392cfSJens Axboe */ 4803d6392cfSJens Axboe ret = 0; 4813d6392cfSJens Axboe do { 48225fd1643SJens Axboe ret = bsg_io_schedule(bd); 4833d6392cfSJens Axboe /* 4843d6392cfSJens Axboe * look for -ENODATA specifically -- we'll sometimes get 4853d6392cfSJens Axboe * -ERESTARTSYS when we've taken a signal, but we can't 4863d6392cfSJens Axboe * return until we're done freeing the queue, so ignore 4873d6392cfSJens Axboe * it. The signal will get handled when we're done freeing 4883d6392cfSJens Axboe * the bsg_device. 4893d6392cfSJens Axboe */ 4903d6392cfSJens Axboe } while (ret != -ENODATA); 4913d6392cfSJens Axboe 4923d6392cfSJens Axboe /* 4933d6392cfSJens Axboe * discard done commands 4943d6392cfSJens Axboe */ 4953d6392cfSJens Axboe ret = 0; 4963d6392cfSJens Axboe do { 497e7d72173SFUJITA Tomonori spin_lock_irq(&bd->lock); 498e7d72173SFUJITA Tomonori if (!bd->queued_cmds) { 499e7d72173SFUJITA Tomonori spin_unlock_irq(&bd->lock); 5003d6392cfSJens Axboe break; 5013d6392cfSJens Axboe } 502efba1a31SFUJITA Tomonori spin_unlock_irq(&bd->lock); 5033d6392cfSJens Axboe 504e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 505e7d72173SFUJITA Tomonori if (IS_ERR(bc)) 506e7d72173SFUJITA Tomonori break; 507e7d72173SFUJITA Tomonori 5082c9ecdf4SFUJITA Tomonori tret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 5092c9ecdf4SFUJITA Tomonori bc->bidi_bio); 5103d6392cfSJens Axboe if (!ret) 5113d6392cfSJens Axboe ret = tret; 5123d6392cfSJens Axboe 5133d6392cfSJens Axboe bsg_free_command(bc); 5143d6392cfSJens Axboe } while (1); 5153d6392cfSJens Axboe 5163d6392cfSJens Axboe return ret; 5173d6392cfSJens Axboe } 5183d6392cfSJens Axboe 51925fd1643SJens Axboe static int 520e7d72173SFUJITA Tomonori __bsg_read(char __user *buf, size_t count, struct bsg_device *bd, 521e7d72173SFUJITA Tomonori const struct iovec *iov, ssize_t *bytes_read) 5223d6392cfSJens Axboe { 5233d6392cfSJens Axboe struct bsg_command *bc; 5243d6392cfSJens Axboe int nr_commands, ret; 5253d6392cfSJens Axboe 52670e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 5273d6392cfSJens Axboe return -EINVAL; 5283d6392cfSJens Axboe 5293d6392cfSJens Axboe ret = 0; 53070e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 5313d6392cfSJens Axboe while (nr_commands) { 532e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 5333d6392cfSJens Axboe if (IS_ERR(bc)) { 5343d6392cfSJens Axboe ret = PTR_ERR(bc); 5353d6392cfSJens Axboe break; 5363d6392cfSJens Axboe } 5373d6392cfSJens Axboe 5383d6392cfSJens Axboe /* 5393d6392cfSJens Axboe * this is the only case where we need to copy data back 5403d6392cfSJens Axboe * after completing the request. so do that here, 5413d6392cfSJens Axboe * bsg_complete_work() cannot do that for us 5423d6392cfSJens Axboe */ 5432c9ecdf4SFUJITA Tomonori ret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 5442c9ecdf4SFUJITA Tomonori bc->bidi_bio); 5453d6392cfSJens Axboe 54625fd1643SJens Axboe if (copy_to_user(buf, &bc->hdr, sizeof(bc->hdr))) 5473d6392cfSJens Axboe ret = -EFAULT; 5483d6392cfSJens Axboe 5493d6392cfSJens Axboe bsg_free_command(bc); 5503d6392cfSJens Axboe 5513d6392cfSJens Axboe if (ret) 5523d6392cfSJens Axboe break; 5533d6392cfSJens Axboe 55470e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 55570e36eceSFUJITA Tomonori *bytes_read += sizeof(struct sg_io_v4); 5563d6392cfSJens Axboe nr_commands--; 5573d6392cfSJens Axboe } 5583d6392cfSJens Axboe 5593d6392cfSJens Axboe return ret; 5603d6392cfSJens Axboe } 5613d6392cfSJens Axboe 5623d6392cfSJens Axboe static inline void bsg_set_block(struct bsg_device *bd, struct file *file) 5633d6392cfSJens Axboe { 5643d6392cfSJens Axboe if (file->f_flags & O_NONBLOCK) 5653d6392cfSJens Axboe clear_bit(BSG_F_BLOCK, &bd->flags); 5663d6392cfSJens Axboe else 5673d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 5683d6392cfSJens Axboe } 5693d6392cfSJens Axboe 5703d6392cfSJens Axboe static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) 5713d6392cfSJens Axboe { 5723d6392cfSJens Axboe if (file->f_mode & FMODE_WRITE) 5733d6392cfSJens Axboe set_bit(BSG_F_WRITE_PERM, &bd->flags); 5743d6392cfSJens Axboe else 5753d6392cfSJens Axboe clear_bit(BSG_F_WRITE_PERM, &bd->flags); 5763d6392cfSJens Axboe } 5773d6392cfSJens Axboe 57825fd1643SJens Axboe /* 57925fd1643SJens Axboe * Check if the error is a "real" error that we should return. 58025fd1643SJens Axboe */ 5813d6392cfSJens Axboe static inline int err_block_err(int ret) 5823d6392cfSJens Axboe { 5833d6392cfSJens Axboe if (ret && ret != -ENOSPC && ret != -ENODATA && ret != -EAGAIN) 5843d6392cfSJens Axboe return 1; 5853d6392cfSJens Axboe 5863d6392cfSJens Axboe return 0; 5873d6392cfSJens Axboe } 5883d6392cfSJens Axboe 5893d6392cfSJens Axboe static ssize_t 5903d6392cfSJens Axboe bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 5913d6392cfSJens Axboe { 5923d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 5933d6392cfSJens Axboe int ret; 5943d6392cfSJens Axboe ssize_t bytes_read; 5953d6392cfSJens Axboe 5969e69fbb5SFUJITA Tomonori dprintk("%s: read %Zd bytes\n", bd->name, count); 5973d6392cfSJens Axboe 5983d6392cfSJens Axboe bsg_set_block(bd, file); 5993d6392cfSJens Axboe bytes_read = 0; 600e7d72173SFUJITA Tomonori ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 6013d6392cfSJens Axboe *ppos = bytes_read; 6023d6392cfSJens Axboe 6033d6392cfSJens Axboe if (!bytes_read || (bytes_read && err_block_err(ret))) 6043d6392cfSJens Axboe bytes_read = ret; 6053d6392cfSJens Axboe 6063d6392cfSJens Axboe return bytes_read; 6073d6392cfSJens Axboe } 6083d6392cfSJens Axboe 60925fd1643SJens Axboe static int __bsg_write(struct bsg_device *bd, const char __user *buf, 61025fd1643SJens Axboe size_t count, ssize_t *bytes_written) 6113d6392cfSJens Axboe { 6123d6392cfSJens Axboe struct bsg_command *bc; 6133d6392cfSJens Axboe struct request *rq; 6143d6392cfSJens Axboe int ret, nr_commands; 6153d6392cfSJens Axboe 61670e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 6173d6392cfSJens Axboe return -EINVAL; 6183d6392cfSJens Axboe 61970e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 6203d6392cfSJens Axboe rq = NULL; 6213d6392cfSJens Axboe bc = NULL; 6223d6392cfSJens Axboe ret = 0; 6233d6392cfSJens Axboe while (nr_commands) { 624165125e1SJens Axboe struct request_queue *q = bd->queue; 6253d6392cfSJens Axboe 626e7d72173SFUJITA Tomonori bc = bsg_alloc_command(bd); 6273d6392cfSJens Axboe if (IS_ERR(bc)) { 6283d6392cfSJens Axboe ret = PTR_ERR(bc); 6293d6392cfSJens Axboe bc = NULL; 6303d6392cfSJens Axboe break; 6313d6392cfSJens Axboe } 6323d6392cfSJens Axboe 6333d6392cfSJens Axboe if (copy_from_user(&bc->hdr, buf, sizeof(bc->hdr))) { 6343d6392cfSJens Axboe ret = -EFAULT; 6353d6392cfSJens Axboe break; 6363d6392cfSJens Axboe } 6373d6392cfSJens Axboe 6383d6392cfSJens Axboe /* 6393d6392cfSJens Axboe * get a request, fill in the blanks, and add to request queue 6403d6392cfSJens Axboe */ 64170e36eceSFUJITA Tomonori rq = bsg_map_hdr(bd, &bc->hdr); 6423d6392cfSJens Axboe if (IS_ERR(rq)) { 6433d6392cfSJens Axboe ret = PTR_ERR(rq); 6443d6392cfSJens Axboe rq = NULL; 6453d6392cfSJens Axboe break; 6463d6392cfSJens Axboe } 6473d6392cfSJens Axboe 6483d6392cfSJens Axboe bsg_add_command(bd, q, bc, rq); 6493d6392cfSJens Axboe bc = NULL; 6503d6392cfSJens Axboe rq = NULL; 6513d6392cfSJens Axboe nr_commands--; 65270e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 65325fd1643SJens Axboe *bytes_written += sizeof(struct sg_io_v4); 6543d6392cfSJens Axboe } 6553d6392cfSJens Axboe 6563d6392cfSJens Axboe if (bc) 6573d6392cfSJens Axboe bsg_free_command(bc); 6583d6392cfSJens Axboe 6593d6392cfSJens Axboe return ret; 6603d6392cfSJens Axboe } 6613d6392cfSJens Axboe 6623d6392cfSJens Axboe static ssize_t 6633d6392cfSJens Axboe bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 6643d6392cfSJens Axboe { 6653d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 66625fd1643SJens Axboe ssize_t bytes_written; 6673d6392cfSJens Axboe int ret; 6683d6392cfSJens Axboe 6699e69fbb5SFUJITA Tomonori dprintk("%s: write %Zd bytes\n", bd->name, count); 6703d6392cfSJens Axboe 6713d6392cfSJens Axboe bsg_set_block(bd, file); 6723d6392cfSJens Axboe bsg_set_write_perm(bd, file); 6733d6392cfSJens Axboe 67425fd1643SJens Axboe bytes_written = 0; 67525fd1643SJens Axboe ret = __bsg_write(bd, buf, count, &bytes_written); 67625fd1643SJens Axboe *ppos = bytes_written; 6773d6392cfSJens Axboe 6783d6392cfSJens Axboe /* 6793d6392cfSJens Axboe * return bytes written on non-fatal errors 6803d6392cfSJens Axboe */ 68125fd1643SJens Axboe if (!bytes_written || (bytes_written && err_block_err(ret))) 68225fd1643SJens Axboe bytes_written = ret; 6833d6392cfSJens Axboe 68425fd1643SJens Axboe dprintk("%s: returning %Zd\n", bd->name, bytes_written); 68525fd1643SJens Axboe return bytes_written; 6863d6392cfSJens Axboe } 6873d6392cfSJens Axboe 6883d6392cfSJens Axboe static struct bsg_device *bsg_alloc_device(void) 6893d6392cfSJens Axboe { 6903d6392cfSJens Axboe struct bsg_device *bd; 6913d6392cfSJens Axboe 6923d6392cfSJens Axboe bd = kzalloc(sizeof(struct bsg_device), GFP_KERNEL); 6933d6392cfSJens Axboe if (unlikely(!bd)) 6943d6392cfSJens Axboe return NULL; 6953d6392cfSJens Axboe 6963d6392cfSJens Axboe spin_lock_init(&bd->lock); 6973d6392cfSJens Axboe 6985309cb38SJens Axboe bd->max_queue = BSG_DEFAULT_CMDS; 6993d6392cfSJens Axboe 7003d6392cfSJens Axboe INIT_LIST_HEAD(&bd->busy_list); 7013d6392cfSJens Axboe INIT_LIST_HEAD(&bd->done_list); 7023d6392cfSJens Axboe INIT_HLIST_NODE(&bd->dev_list); 7033d6392cfSJens Axboe 7043d6392cfSJens Axboe init_waitqueue_head(&bd->wq_free); 7053d6392cfSJens Axboe init_waitqueue_head(&bd->wq_done); 7063d6392cfSJens Axboe return bd; 7073d6392cfSJens Axboe } 7083d6392cfSJens Axboe 70997f46ae4SFUJITA Tomonori static void bsg_kref_release_function(struct kref *kref) 71097f46ae4SFUJITA Tomonori { 71197f46ae4SFUJITA Tomonori struct bsg_class_device *bcd = 71297f46ae4SFUJITA Tomonori container_of(kref, struct bsg_class_device, ref); 71397f46ae4SFUJITA Tomonori 71497f46ae4SFUJITA Tomonori if (bcd->release) 71597f46ae4SFUJITA Tomonori bcd->release(bcd->parent); 71697f46ae4SFUJITA Tomonori 71797f46ae4SFUJITA Tomonori put_device(bcd->parent); 71897f46ae4SFUJITA Tomonori } 71997f46ae4SFUJITA Tomonori 7203d6392cfSJens Axboe static int bsg_put_device(struct bsg_device *bd) 7213d6392cfSJens Axboe { 72297f46ae4SFUJITA Tomonori int ret = 0, do_free; 72397f46ae4SFUJITA Tomonori struct request_queue *q = bd->queue; 7243d6392cfSJens Axboe 7253d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7263d6392cfSJens Axboe 72797f46ae4SFUJITA Tomonori do_free = atomic_dec_and_test(&bd->ref_count); 72897f46ae4SFUJITA Tomonori if (!do_free) 7293d6392cfSJens Axboe goto out; 7303d6392cfSJens Axboe 7313d6392cfSJens Axboe dprintk("%s: tearing down\n", bd->name); 7323d6392cfSJens Axboe 7333d6392cfSJens Axboe /* 7343d6392cfSJens Axboe * close can always block 7353d6392cfSJens Axboe */ 7363d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 7373d6392cfSJens Axboe 7383d6392cfSJens Axboe /* 7393d6392cfSJens Axboe * correct error detection baddies here again. it's the responsibility 7403d6392cfSJens Axboe * of the app to properly reap commands before close() if it wants 7413d6392cfSJens Axboe * fool-proof error detection 7423d6392cfSJens Axboe */ 7433d6392cfSJens Axboe ret = bsg_complete_all_commands(bd); 7443d6392cfSJens Axboe 7453d6392cfSJens Axboe hlist_del(&bd->dev_list); 7465309cb38SJens Axboe kfree(bd); 7473d6392cfSJens Axboe out: 7483d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 74997f46ae4SFUJITA Tomonori kref_put(&q->bsg_dev.ref, bsg_kref_release_function); 75097f46ae4SFUJITA Tomonori if (do_free) 75197f46ae4SFUJITA Tomonori blk_put_queue(q); 7523d6392cfSJens Axboe return ret; 7533d6392cfSJens Axboe } 7543d6392cfSJens Axboe 7553d6392cfSJens Axboe static struct bsg_device *bsg_add_device(struct inode *inode, 756d351af01SFUJITA Tomonori struct request_queue *rq, 7573d6392cfSJens Axboe struct file *file) 7583d6392cfSJens Axboe { 75925fd1643SJens Axboe struct bsg_device *bd; 760c3ff1b90SFUJITA Tomonori int ret; 7613d6392cfSJens Axboe #ifdef BSG_DEBUG 7623d6392cfSJens Axboe unsigned char buf[32]; 7633d6392cfSJens Axboe #endif 764c3ff1b90SFUJITA Tomonori ret = blk_get_queue(rq); 765c3ff1b90SFUJITA Tomonori if (ret) 766c3ff1b90SFUJITA Tomonori return ERR_PTR(-ENXIO); 7673d6392cfSJens Axboe 7683d6392cfSJens Axboe bd = bsg_alloc_device(); 769c3ff1b90SFUJITA Tomonori if (!bd) { 770c3ff1b90SFUJITA Tomonori blk_put_queue(rq); 7713d6392cfSJens Axboe return ERR_PTR(-ENOMEM); 772c3ff1b90SFUJITA Tomonori } 7733d6392cfSJens Axboe 774d351af01SFUJITA Tomonori bd->queue = rq; 7753d6392cfSJens Axboe bsg_set_block(bd, file); 7763d6392cfSJens Axboe 7773d6392cfSJens Axboe atomic_set(&bd->ref_count, 1); 7783d6392cfSJens Axboe mutex_lock(&bsg_mutex); 779842ea771SFUJITA Tomonori hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode))); 7803d6392cfSJens Axboe 781ee959b00STony Jones strncpy(bd->name, rq->bsg_dev.class_dev->bus_id, sizeof(bd->name) - 1); 7823d6392cfSJens Axboe dprintk("bound to <%s>, max queue %d\n", 7839e69fbb5SFUJITA Tomonori format_dev_t(buf, inode->i_rdev), bd->max_queue); 7843d6392cfSJens Axboe 7853d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7863d6392cfSJens Axboe return bd; 7873d6392cfSJens Axboe } 7883d6392cfSJens Axboe 789842ea771SFUJITA Tomonori static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q) 7903d6392cfSJens Axboe { 79143ac9e62SFUJITA Tomonori struct bsg_device *bd; 7923d6392cfSJens Axboe struct hlist_node *entry; 7933d6392cfSJens Axboe 7943d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7953d6392cfSJens Axboe 79643ac9e62SFUJITA Tomonori hlist_for_each_entry(bd, entry, bsg_dev_idx_hash(minor), dev_list) { 797842ea771SFUJITA Tomonori if (bd->queue == q) { 7983d6392cfSJens Axboe atomic_inc(&bd->ref_count); 79943ac9e62SFUJITA Tomonori goto found; 8003d6392cfSJens Axboe } 80143ac9e62SFUJITA Tomonori } 8023d6392cfSJens Axboe bd = NULL; 80343ac9e62SFUJITA Tomonori found: 8043d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 8053d6392cfSJens Axboe return bd; 8063d6392cfSJens Axboe } 8073d6392cfSJens Axboe 8083d6392cfSJens Axboe static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) 8093d6392cfSJens Axboe { 810598443a2SFUJITA Tomonori struct bsg_device *bd; 811598443a2SFUJITA Tomonori struct bsg_class_device *bcd; 8123d6392cfSJens Axboe 8133d6392cfSJens Axboe /* 8143d6392cfSJens Axboe * find the class device 8153d6392cfSJens Axboe */ 8163d6392cfSJens Axboe mutex_lock(&bsg_mutex); 817598443a2SFUJITA Tomonori bcd = idr_find(&bsg_minor_idr, iminor(inode)); 818d45ac4faSFUJITA Tomonori if (bcd) 81997f46ae4SFUJITA Tomonori kref_get(&bcd->ref); 8203d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 8213d6392cfSJens Axboe 8223d6392cfSJens Axboe if (!bcd) 8233d6392cfSJens Axboe return ERR_PTR(-ENODEV); 8243d6392cfSJens Axboe 825842ea771SFUJITA Tomonori bd = __bsg_get_device(iminor(inode), bcd->queue); 826d45ac4faSFUJITA Tomonori if (bd) 827d45ac4faSFUJITA Tomonori return bd; 828d45ac4faSFUJITA Tomonori 829d45ac4faSFUJITA Tomonori bd = bsg_add_device(inode, bcd->queue, file); 830d45ac4faSFUJITA Tomonori if (IS_ERR(bd)) 83197f46ae4SFUJITA Tomonori kref_put(&bcd->ref, bsg_kref_release_function); 832d45ac4faSFUJITA Tomonori 833d45ac4faSFUJITA Tomonori return bd; 8343d6392cfSJens Axboe } 8353d6392cfSJens Axboe 8363d6392cfSJens Axboe static int bsg_open(struct inode *inode, struct file *file) 8373d6392cfSJens Axboe { 838*75bd2ef1SJonathan Corbet struct bsg_device *bd; 839*75bd2ef1SJonathan Corbet 840*75bd2ef1SJonathan Corbet lock_kernel(); 841*75bd2ef1SJonathan Corbet bd = bsg_get_device(inode, file); 842*75bd2ef1SJonathan Corbet unlock_kernel(); 8433d6392cfSJens Axboe 8443d6392cfSJens Axboe if (IS_ERR(bd)) 8453d6392cfSJens Axboe return PTR_ERR(bd); 8463d6392cfSJens Axboe 8473d6392cfSJens Axboe file->private_data = bd; 8483d6392cfSJens Axboe return 0; 8493d6392cfSJens Axboe } 8503d6392cfSJens Axboe 8513d6392cfSJens Axboe static int bsg_release(struct inode *inode, struct file *file) 8523d6392cfSJens Axboe { 8533d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8543d6392cfSJens Axboe 8553d6392cfSJens Axboe file->private_data = NULL; 8563d6392cfSJens Axboe return bsg_put_device(bd); 8573d6392cfSJens Axboe } 8583d6392cfSJens Axboe 8593d6392cfSJens Axboe static unsigned int bsg_poll(struct file *file, poll_table *wait) 8603d6392cfSJens Axboe { 8613d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8623d6392cfSJens Axboe unsigned int mask = 0; 8633d6392cfSJens Axboe 8643d6392cfSJens Axboe poll_wait(file, &bd->wq_done, wait); 8653d6392cfSJens Axboe poll_wait(file, &bd->wq_free, wait); 8663d6392cfSJens Axboe 8673d6392cfSJens Axboe spin_lock_irq(&bd->lock); 8683d6392cfSJens Axboe if (!list_empty(&bd->done_list)) 8693d6392cfSJens Axboe mask |= POLLIN | POLLRDNORM; 8703d6392cfSJens Axboe if (bd->queued_cmds >= bd->max_queue) 8713d6392cfSJens Axboe mask |= POLLOUT; 8723d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 8733d6392cfSJens Axboe 8743d6392cfSJens Axboe return mask; 8753d6392cfSJens Axboe } 8763d6392cfSJens Axboe 87725fd1643SJens Axboe static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 8783d6392cfSJens Axboe { 8793d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8803d6392cfSJens Axboe int __user *uarg = (int __user *) arg; 8812d507a01SJames Bottomley int ret; 8823d6392cfSJens Axboe 8833d6392cfSJens Axboe switch (cmd) { 8843d6392cfSJens Axboe /* 8853d6392cfSJens Axboe * our own ioctls 8863d6392cfSJens Axboe */ 8873d6392cfSJens Axboe case SG_GET_COMMAND_Q: 8883d6392cfSJens Axboe return put_user(bd->max_queue, uarg); 8893d6392cfSJens Axboe case SG_SET_COMMAND_Q: { 8903d6392cfSJens Axboe int queue; 8913d6392cfSJens Axboe 8923d6392cfSJens Axboe if (get_user(queue, uarg)) 8933d6392cfSJens Axboe return -EFAULT; 8945309cb38SJens Axboe if (queue < 1) 8953d6392cfSJens Axboe return -EINVAL; 8963d6392cfSJens Axboe 8975309cb38SJens Axboe spin_lock_irq(&bd->lock); 8983d6392cfSJens Axboe bd->max_queue = queue; 8995309cb38SJens Axboe spin_unlock_irq(&bd->lock); 9003d6392cfSJens Axboe return 0; 9013d6392cfSJens Axboe } 9023d6392cfSJens Axboe 9033d6392cfSJens Axboe /* 9043d6392cfSJens Axboe * SCSI/sg ioctls 9053d6392cfSJens Axboe */ 9063d6392cfSJens Axboe case SG_GET_VERSION_NUM: 9073d6392cfSJens Axboe case SCSI_IOCTL_GET_IDLUN: 9083d6392cfSJens Axboe case SCSI_IOCTL_GET_BUS_NUMBER: 9093d6392cfSJens Axboe case SG_SET_TIMEOUT: 9103d6392cfSJens Axboe case SG_GET_TIMEOUT: 9113d6392cfSJens Axboe case SG_GET_RESERVED_SIZE: 9123d6392cfSJens Axboe case SG_SET_RESERVED_SIZE: 9133d6392cfSJens Axboe case SG_EMULATED_HOST: 9143d6392cfSJens Axboe case SCSI_IOCTL_SEND_COMMAND: { 9153d6392cfSJens Axboe void __user *uarg = (void __user *) arg; 916d351af01SFUJITA Tomonori return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); 9173d6392cfSJens Axboe } 91810e8855bSFUJITA Tomonori case SG_IO: { 91910e8855bSFUJITA Tomonori struct request *rq; 9202c9ecdf4SFUJITA Tomonori struct bio *bio, *bidi_bio = NULL; 92110e8855bSFUJITA Tomonori struct sg_io_v4 hdr; 92210e8855bSFUJITA Tomonori 92310e8855bSFUJITA Tomonori if (copy_from_user(&hdr, uarg, sizeof(hdr))) 92410e8855bSFUJITA Tomonori return -EFAULT; 92510e8855bSFUJITA Tomonori 92610e8855bSFUJITA Tomonori rq = bsg_map_hdr(bd, &hdr); 92710e8855bSFUJITA Tomonori if (IS_ERR(rq)) 92810e8855bSFUJITA Tomonori return PTR_ERR(rq); 92910e8855bSFUJITA Tomonori 93010e8855bSFUJITA Tomonori bio = rq->bio; 9312c9ecdf4SFUJITA Tomonori if (rq->next_rq) 9322c9ecdf4SFUJITA Tomonori bidi_bio = rq->next_rq->bio; 933d351af01SFUJITA Tomonori blk_execute_rq(bd->queue, NULL, rq, 0); 9342d507a01SJames Bottomley ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); 93510e8855bSFUJITA Tomonori 93610e8855bSFUJITA Tomonori if (copy_to_user(uarg, &hdr, sizeof(hdr))) 93710e8855bSFUJITA Tomonori return -EFAULT; 938b711afa6SJens Axboe 9392d507a01SJames Bottomley return ret; 94010e8855bSFUJITA Tomonori } 9413d6392cfSJens Axboe /* 9423d6392cfSJens Axboe * block device ioctls 9433d6392cfSJens Axboe */ 9443d6392cfSJens Axboe default: 9453d6392cfSJens Axboe #if 0 9463d6392cfSJens Axboe return ioctl_by_bdev(bd->bdev, cmd, arg); 9473d6392cfSJens Axboe #else 9483d6392cfSJens Axboe return -ENOTTY; 9493d6392cfSJens Axboe #endif 9503d6392cfSJens Axboe } 9513d6392cfSJens Axboe } 9523d6392cfSJens Axboe 9537344be05SArjan van de Ven static const struct file_operations bsg_fops = { 9543d6392cfSJens Axboe .read = bsg_read, 9553d6392cfSJens Axboe .write = bsg_write, 9563d6392cfSJens Axboe .poll = bsg_poll, 9573d6392cfSJens Axboe .open = bsg_open, 9583d6392cfSJens Axboe .release = bsg_release, 95925fd1643SJens Axboe .unlocked_ioctl = bsg_ioctl, 9603d6392cfSJens Axboe .owner = THIS_MODULE, 9613d6392cfSJens Axboe }; 9623d6392cfSJens Axboe 963d351af01SFUJITA Tomonori void bsg_unregister_queue(struct request_queue *q) 9643d6392cfSJens Axboe { 965d351af01SFUJITA Tomonori struct bsg_class_device *bcd = &q->bsg_dev; 9663d6392cfSJens Axboe 967df468820SFUJITA Tomonori if (!bcd->class_dev) 968df468820SFUJITA Tomonori return; 9693d6392cfSJens Axboe 9703d6392cfSJens Axboe mutex_lock(&bsg_mutex); 971598443a2SFUJITA Tomonori idr_remove(&bsg_minor_idr, bcd->minor); 972d351af01SFUJITA Tomonori sysfs_remove_link(&q->kobj, "bsg"); 973ee959b00STony Jones device_unregister(bcd->class_dev); 9743d6392cfSJens Axboe bcd->class_dev = NULL; 97597f46ae4SFUJITA Tomonori kref_put(&bcd->ref, bsg_kref_release_function); 9763d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 9773d6392cfSJens Axboe } 9784cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_unregister_queue); 9793d6392cfSJens Axboe 98097f46ae4SFUJITA Tomonori int bsg_register_queue(struct request_queue *q, struct device *parent, 98197f46ae4SFUJITA Tomonori const char *name, void (*release)(struct device *)) 9823d6392cfSJens Axboe { 983598443a2SFUJITA Tomonori struct bsg_class_device *bcd; 9843d6392cfSJens Axboe dev_t dev; 985598443a2SFUJITA Tomonori int ret, minor; 986ee959b00STony Jones struct device *class_dev = NULL; 98739dca558SJames Bottomley const char *devname; 98839dca558SJames Bottomley 98939dca558SJames Bottomley if (name) 99039dca558SJames Bottomley devname = name; 99139dca558SJames Bottomley else 99297f46ae4SFUJITA Tomonori devname = parent->bus_id; 9933d6392cfSJens Axboe 9943d6392cfSJens Axboe /* 9953d6392cfSJens Axboe * we need a proper transport to send commands, not a stacked device 9963d6392cfSJens Axboe */ 9973d6392cfSJens Axboe if (!q->request_fn) 9983d6392cfSJens Axboe return 0; 9993d6392cfSJens Axboe 1000d351af01SFUJITA Tomonori bcd = &q->bsg_dev; 10013d6392cfSJens Axboe memset(bcd, 0, sizeof(*bcd)); 10023d6392cfSJens Axboe 10033d6392cfSJens Axboe mutex_lock(&bsg_mutex); 1004598443a2SFUJITA Tomonori 1005598443a2SFUJITA Tomonori ret = idr_pre_get(&bsg_minor_idr, GFP_KERNEL); 1006598443a2SFUJITA Tomonori if (!ret) { 1007598443a2SFUJITA Tomonori ret = -ENOMEM; 1008598443a2SFUJITA Tomonori goto unlock; 1009598443a2SFUJITA Tomonori } 1010598443a2SFUJITA Tomonori 1011598443a2SFUJITA Tomonori ret = idr_get_new(&bsg_minor_idr, bcd, &minor); 1012598443a2SFUJITA Tomonori if (ret < 0) 1013598443a2SFUJITA Tomonori goto unlock; 1014598443a2SFUJITA Tomonori 1015598443a2SFUJITA Tomonori if (minor >= BSG_MAX_DEVS) { 1016292b7f27SFUJITA Tomonori printk(KERN_ERR "bsg: too many bsg devices\n"); 1017598443a2SFUJITA Tomonori ret = -EINVAL; 1018598443a2SFUJITA Tomonori goto remove_idr; 1019292b7f27SFUJITA Tomonori } 1020292b7f27SFUJITA Tomonori 1021598443a2SFUJITA Tomonori bcd->minor = minor; 1022d351af01SFUJITA Tomonori bcd->queue = q; 102397f46ae4SFUJITA Tomonori bcd->parent = get_device(parent); 102497f46ae4SFUJITA Tomonori bcd->release = release; 102597f46ae4SFUJITA Tomonori kref_init(&bcd->ref); 102646f6ef4aSJens Axboe dev = MKDEV(bsg_major, bcd->minor); 102797f46ae4SFUJITA Tomonori class_dev = device_create(bsg_class, parent, dev, "%s", devname); 10284e2872d6SFUJITA Tomonori if (IS_ERR(class_dev)) { 10294e2872d6SFUJITA Tomonori ret = PTR_ERR(class_dev); 1030598443a2SFUJITA Tomonori goto put_dev; 10314e2872d6SFUJITA Tomonori } 10324e2872d6SFUJITA Tomonori bcd->class_dev = class_dev; 10334e2872d6SFUJITA Tomonori 1034abce891aSLinus Torvalds if (q->kobj.sd) { 10354e2872d6SFUJITA Tomonori ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); 10364e2872d6SFUJITA Tomonori if (ret) 1037598443a2SFUJITA Tomonori goto unregister_class_dev; 10384e2872d6SFUJITA Tomonori } 10394e2872d6SFUJITA Tomonori 10403d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 10413d6392cfSJens Axboe return 0; 10426826ee4fSJames Bottomley 1043598443a2SFUJITA Tomonori unregister_class_dev: 1044ee959b00STony Jones device_unregister(class_dev); 1045598443a2SFUJITA Tomonori put_dev: 104697f46ae4SFUJITA Tomonori put_device(parent); 1047598443a2SFUJITA Tomonori remove_idr: 1048598443a2SFUJITA Tomonori idr_remove(&bsg_minor_idr, minor); 1049598443a2SFUJITA Tomonori unlock: 1050264a0472SJens Axboe mutex_unlock(&bsg_mutex); 10514e2872d6SFUJITA Tomonori return ret; 10523d6392cfSJens Axboe } 10534cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_register_queue); 10543d6392cfSJens Axboe 10557e7654a9SGreg Kroah-Hartman static struct cdev bsg_cdev; 1056292b7f27SFUJITA Tomonori 10573d6392cfSJens Axboe static int __init bsg_init(void) 10583d6392cfSJens Axboe { 10593d6392cfSJens Axboe int ret, i; 106046f6ef4aSJens Axboe dev_t devid; 10613d6392cfSJens Axboe 10625309cb38SJens Axboe bsg_cmd_cachep = kmem_cache_create("bsg_cmd", 106320c2df83SPaul Mundt sizeof(struct bsg_command), 0, 0, NULL); 10645309cb38SJens Axboe if (!bsg_cmd_cachep) { 10655309cb38SJens Axboe printk(KERN_ERR "bsg: failed creating slab cache\n"); 10665309cb38SJens Axboe return -ENOMEM; 10675309cb38SJens Axboe } 10685309cb38SJens Axboe 106925fd1643SJens Axboe for (i = 0; i < BSG_LIST_ARRAY_SIZE; i++) 10703d6392cfSJens Axboe INIT_HLIST_HEAD(&bsg_device_list[i]); 10713d6392cfSJens Axboe 10723d6392cfSJens Axboe bsg_class = class_create(THIS_MODULE, "bsg"); 10735309cb38SJens Axboe if (IS_ERR(bsg_class)) { 10749b9f770cSFUJITA Tomonori ret = PTR_ERR(bsg_class); 10759b9f770cSFUJITA Tomonori goto destroy_kmemcache; 10765309cb38SJens Axboe } 10773d6392cfSJens Axboe 107846f6ef4aSJens Axboe ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg"); 10799b9f770cSFUJITA Tomonori if (ret) 10809b9f770cSFUJITA Tomonori goto destroy_bsg_class; 10813d6392cfSJens Axboe 108246f6ef4aSJens Axboe bsg_major = MAJOR(devid); 108346f6ef4aSJens Axboe 1084292b7f27SFUJITA Tomonori cdev_init(&bsg_cdev, &bsg_fops); 108546f6ef4aSJens Axboe ret = cdev_add(&bsg_cdev, MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10869b9f770cSFUJITA Tomonori if (ret) 10879b9f770cSFUJITA Tomonori goto unregister_chrdev; 1088292b7f27SFUJITA Tomonori 10890ed081ceSFUJITA Tomonori printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION 10900ed081ceSFUJITA Tomonori " loaded (major %d)\n", bsg_major); 10913d6392cfSJens Axboe return 0; 10929b9f770cSFUJITA Tomonori unregister_chrdev: 10939b9f770cSFUJITA Tomonori unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10949b9f770cSFUJITA Tomonori destroy_bsg_class: 10959b9f770cSFUJITA Tomonori class_destroy(bsg_class); 10969b9f770cSFUJITA Tomonori destroy_kmemcache: 10979b9f770cSFUJITA Tomonori kmem_cache_destroy(bsg_cmd_cachep); 10989b9f770cSFUJITA Tomonori return ret; 10993d6392cfSJens Axboe } 11003d6392cfSJens Axboe 11013d6392cfSJens Axboe MODULE_AUTHOR("Jens Axboe"); 11020ed081ceSFUJITA Tomonori MODULE_DESCRIPTION(BSG_DESCRIPTION); 11033d6392cfSJens Axboe MODULE_LICENSE("GPL"); 11043d6392cfSJens Axboe 11054e2872d6SFUJITA Tomonori device_initcall(bsg_init); 1106