13d6392cfSJens Axboe /* 23d6392cfSJens Axboe * bsg.c - block layer implementation of the sg v3 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 /* 133d6392cfSJens Axboe * TODO 143d6392cfSJens Axboe * - Should this get merged, block/scsi_ioctl.c will be migrated into 153d6392cfSJens Axboe * this file. To keep maintenance down, it's easier to have them 163d6392cfSJens Axboe * seperated right now. 173d6392cfSJens Axboe * 183d6392cfSJens Axboe */ 193d6392cfSJens Axboe #include <linux/module.h> 203d6392cfSJens Axboe #include <linux/init.h> 213d6392cfSJens Axboe #include <linux/file.h> 223d6392cfSJens Axboe #include <linux/blkdev.h> 233d6392cfSJens Axboe #include <linux/poll.h> 243d6392cfSJens Axboe #include <linux/cdev.h> 253d6392cfSJens Axboe #include <linux/percpu.h> 263d6392cfSJens Axboe #include <linux/uio.h> 273d6392cfSJens Axboe #include <linux/bsg.h> 283d6392cfSJens Axboe 293d6392cfSJens Axboe #include <scsi/scsi.h> 303d6392cfSJens Axboe #include <scsi/scsi_ioctl.h> 313d6392cfSJens Axboe #include <scsi/scsi_cmnd.h> 324e2872d6SFUJITA Tomonori #include <scsi/scsi_device.h> 334e2872d6SFUJITA Tomonori #include <scsi/scsi_driver.h> 343d6392cfSJens Axboe #include <scsi/sg.h> 353d6392cfSJens Axboe 360ed081ceSFUJITA Tomonori #define BSG_DESCRIPTION "Block layer SCSI generic (bsg) driver" 370ed081ceSFUJITA Tomonori #define BSG_VERSION "0.4" 383d6392cfSJens Axboe 393d6392cfSJens Axboe struct bsg_device { 40*165125e1SJens Axboe struct request_queue *queue; 413d6392cfSJens Axboe spinlock_t lock; 423d6392cfSJens Axboe struct list_head busy_list; 433d6392cfSJens Axboe struct list_head done_list; 443d6392cfSJens Axboe struct hlist_node dev_list; 453d6392cfSJens Axboe atomic_t ref_count; 463d6392cfSJens Axboe int minor; 473d6392cfSJens Axboe int queued_cmds; 483d6392cfSJens Axboe int done_cmds; 493d6392cfSJens Axboe wait_queue_head_t wq_done; 503d6392cfSJens Axboe wait_queue_head_t wq_free; 51d351af01SFUJITA Tomonori char name[BUS_ID_SIZE]; 523d6392cfSJens Axboe int max_queue; 533d6392cfSJens Axboe unsigned long flags; 543d6392cfSJens Axboe }; 553d6392cfSJens Axboe 563d6392cfSJens Axboe enum { 573d6392cfSJens Axboe BSG_F_BLOCK = 1, 583d6392cfSJens Axboe BSG_F_WRITE_PERM = 2, 593d6392cfSJens Axboe }; 603d6392cfSJens Axboe 615309cb38SJens Axboe #define BSG_DEFAULT_CMDS 64 62292b7f27SFUJITA Tomonori #define BSG_MAX_DEVS 32768 633d6392cfSJens Axboe 643d6392cfSJens Axboe #undef BSG_DEBUG 653d6392cfSJens Axboe 663d6392cfSJens Axboe #ifdef BSG_DEBUG 673d6392cfSJens Axboe #define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ##args) 683d6392cfSJens Axboe #else 693d6392cfSJens Axboe #define dprintk(fmt, args...) 703d6392cfSJens Axboe #endif 713d6392cfSJens Axboe 723d6392cfSJens Axboe static DEFINE_MUTEX(bsg_mutex); 73292b7f27SFUJITA Tomonori static int bsg_device_nr, bsg_minor_idx; 743d6392cfSJens Axboe 7525fd1643SJens Axboe #define BSG_LIST_ARRAY_SIZE 8 7625fd1643SJens Axboe static struct hlist_head bsg_device_list[BSG_LIST_ARRAY_SIZE]; 773d6392cfSJens Axboe 783d6392cfSJens Axboe static struct class *bsg_class; 793d6392cfSJens Axboe static LIST_HEAD(bsg_class_list); 8046f6ef4aSJens Axboe static int bsg_major; 813d6392cfSJens Axboe 825309cb38SJens Axboe static struct kmem_cache *bsg_cmd_cachep; 835309cb38SJens Axboe 843d6392cfSJens Axboe /* 853d6392cfSJens Axboe * our internal command type 863d6392cfSJens Axboe */ 873d6392cfSJens Axboe struct bsg_command { 883d6392cfSJens Axboe struct bsg_device *bd; 893d6392cfSJens Axboe struct list_head list; 903d6392cfSJens Axboe struct request *rq; 913d6392cfSJens Axboe struct bio *bio; 922c9ecdf4SFUJITA Tomonori struct bio *bidi_bio; 933d6392cfSJens Axboe int err; 9470e36eceSFUJITA Tomonori struct sg_io_v4 hdr; 9570e36eceSFUJITA Tomonori struct sg_io_v4 __user *uhdr; 963d6392cfSJens Axboe char sense[SCSI_SENSE_BUFFERSIZE]; 973d6392cfSJens Axboe }; 983d6392cfSJens Axboe 993d6392cfSJens Axboe static void bsg_free_command(struct bsg_command *bc) 1003d6392cfSJens Axboe { 1013d6392cfSJens Axboe struct bsg_device *bd = bc->bd; 1023d6392cfSJens Axboe unsigned long flags; 1033d6392cfSJens Axboe 1045309cb38SJens Axboe kmem_cache_free(bsg_cmd_cachep, bc); 1053d6392cfSJens Axboe 1063d6392cfSJens Axboe spin_lock_irqsave(&bd->lock, flags); 1073d6392cfSJens Axboe bd->queued_cmds--; 1083d6392cfSJens Axboe spin_unlock_irqrestore(&bd->lock, flags); 1093d6392cfSJens Axboe 1103d6392cfSJens Axboe wake_up(&bd->wq_free); 1113d6392cfSJens Axboe } 1123d6392cfSJens Axboe 113e7d72173SFUJITA Tomonori static struct bsg_command *bsg_alloc_command(struct bsg_device *bd) 1143d6392cfSJens Axboe { 115e7d72173SFUJITA Tomonori struct bsg_command *bc = ERR_PTR(-EINVAL); 1163d6392cfSJens Axboe 1173d6392cfSJens Axboe spin_lock_irq(&bd->lock); 1183d6392cfSJens Axboe 1193d6392cfSJens Axboe if (bd->queued_cmds >= bd->max_queue) 1203d6392cfSJens Axboe goto out; 1213d6392cfSJens Axboe 1223d6392cfSJens Axboe bd->queued_cmds++; 1233d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1243d6392cfSJens Axboe 12525fd1643SJens Axboe bc = kmem_cache_zalloc(bsg_cmd_cachep, GFP_KERNEL); 1265309cb38SJens Axboe if (unlikely(!bc)) { 1275309cb38SJens Axboe spin_lock_irq(&bd->lock); 1287e75d730SFUJITA Tomonori bd->queued_cmds--; 129e7d72173SFUJITA Tomonori bc = ERR_PTR(-ENOMEM); 1307e75d730SFUJITA Tomonori goto out; 1315309cb38SJens Axboe } 1325309cb38SJens Axboe 1333d6392cfSJens Axboe bc->bd = bd; 1343d6392cfSJens Axboe INIT_LIST_HEAD(&bc->list); 1355309cb38SJens Axboe dprintk("%s: returning free cmd %p\n", bd->name, bc); 1363d6392cfSJens Axboe return bc; 1373d6392cfSJens Axboe out: 1383d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1393d6392cfSJens Axboe return bc; 1403d6392cfSJens Axboe } 1413d6392cfSJens Axboe 1421c1133e1SFUJITA Tomonori static inline struct hlist_head *bsg_dev_idx_hash(int index) 1433d6392cfSJens Axboe { 1441c1133e1SFUJITA Tomonori return &bsg_device_list[index & (BSG_LIST_ARRAY_SIZE - 1)]; 1453d6392cfSJens Axboe } 1463d6392cfSJens Axboe 14725fd1643SJens Axboe static int bsg_io_schedule(struct bsg_device *bd) 1483d6392cfSJens Axboe { 1493d6392cfSJens Axboe DEFINE_WAIT(wait); 1503d6392cfSJens Axboe int ret = 0; 1513d6392cfSJens Axboe 1523d6392cfSJens Axboe spin_lock_irq(&bd->lock); 1533d6392cfSJens Axboe 1543d6392cfSJens Axboe BUG_ON(bd->done_cmds > bd->queued_cmds); 1553d6392cfSJens Axboe 1563d6392cfSJens Axboe /* 1573d6392cfSJens Axboe * -ENOSPC or -ENODATA? I'm going for -ENODATA, meaning "I have no 1583d6392cfSJens Axboe * work to do", even though we return -ENOSPC after this same test 1593d6392cfSJens Axboe * during bsg_write() -- there, it means our buffer can't have more 1603d6392cfSJens Axboe * bsg_commands added to it, thus has no space left. 1613d6392cfSJens Axboe */ 1623d6392cfSJens Axboe if (bd->done_cmds == bd->queued_cmds) { 1633d6392cfSJens Axboe ret = -ENODATA; 1643d6392cfSJens Axboe goto unlock; 1653d6392cfSJens Axboe } 1663d6392cfSJens Axboe 1673d6392cfSJens Axboe if (!test_bit(BSG_F_BLOCK, &bd->flags)) { 1683d6392cfSJens Axboe ret = -EAGAIN; 1693d6392cfSJens Axboe goto unlock; 1703d6392cfSJens Axboe } 1713d6392cfSJens Axboe 17225fd1643SJens Axboe prepare_to_wait(&bd->wq_done, &wait, TASK_UNINTERRUPTIBLE); 1733d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1743d6392cfSJens Axboe io_schedule(); 1753d6392cfSJens Axboe finish_wait(&bd->wq_done, &wait); 1763d6392cfSJens Axboe 1773d6392cfSJens Axboe return ret; 1783d6392cfSJens Axboe unlock: 1793d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 1803d6392cfSJens Axboe return ret; 1813d6392cfSJens Axboe } 1823d6392cfSJens Axboe 183*165125e1SJens Axboe static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 18470e36eceSFUJITA Tomonori struct sg_io_v4 *hdr, int has_write_perm) 18570e36eceSFUJITA Tomonori { 18670e36eceSFUJITA Tomonori memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ 18770e36eceSFUJITA Tomonori 18870e36eceSFUJITA Tomonori if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, 18970e36eceSFUJITA Tomonori hdr->request_len)) 19070e36eceSFUJITA Tomonori return -EFAULT; 19115d10b61SFUJITA Tomonori 19215d10b61SFUJITA Tomonori if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 19370e36eceSFUJITA Tomonori if (blk_verify_command(rq->cmd, has_write_perm)) 19470e36eceSFUJITA Tomonori return -EPERM; 19515d10b61SFUJITA Tomonori } else if (!capable(CAP_SYS_RAWIO)) 19615d10b61SFUJITA Tomonori return -EPERM; 19770e36eceSFUJITA Tomonori 1983d6392cfSJens Axboe /* 19970e36eceSFUJITA Tomonori * fill in request structure 20070e36eceSFUJITA Tomonori */ 20170e36eceSFUJITA Tomonori rq->cmd_len = hdr->request_len; 20270e36eceSFUJITA Tomonori rq->cmd_type = REQ_TYPE_BLOCK_PC; 20370e36eceSFUJITA Tomonori 20470e36eceSFUJITA Tomonori rq->timeout = (hdr->timeout * HZ) / 1000; 20570e36eceSFUJITA Tomonori if (!rq->timeout) 20670e36eceSFUJITA Tomonori rq->timeout = q->sg_timeout; 20770e36eceSFUJITA Tomonori if (!rq->timeout) 20870e36eceSFUJITA Tomonori rq->timeout = BLK_DEFAULT_SG_TIMEOUT; 20970e36eceSFUJITA Tomonori 21070e36eceSFUJITA Tomonori return 0; 21170e36eceSFUJITA Tomonori } 21270e36eceSFUJITA Tomonori 21370e36eceSFUJITA Tomonori /* 21470e36eceSFUJITA Tomonori * Check if sg_io_v4 from user is allowed and valid 2153d6392cfSJens Axboe */ 2163d6392cfSJens Axboe static int 217*165125e1SJens Axboe bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) 2183d6392cfSJens Axboe { 21915d10b61SFUJITA Tomonori int ret = 0; 22015d10b61SFUJITA Tomonori 22170e36eceSFUJITA Tomonori if (hdr->guard != 'Q') 2223d6392cfSJens Axboe return -EINVAL; 22370e36eceSFUJITA Tomonori if (hdr->request_len > BLK_MAX_CDB) 2243d6392cfSJens Axboe return -EINVAL; 22570e36eceSFUJITA Tomonori if (hdr->dout_xfer_len > (q->max_sectors << 9) || 22670e36eceSFUJITA Tomonori hdr->din_xfer_len > (q->max_sectors << 9)) 2273d6392cfSJens Axboe return -EIO; 2283d6392cfSJens Axboe 22915d10b61SFUJITA Tomonori switch (hdr->protocol) { 23015d10b61SFUJITA Tomonori case BSG_PROTOCOL_SCSI: 23115d10b61SFUJITA Tomonori switch (hdr->subprotocol) { 23215d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_CMD: 23315d10b61SFUJITA Tomonori case BSG_SUB_PROTOCOL_SCSI_TRANSPORT: 23415d10b61SFUJITA Tomonori break; 23515d10b61SFUJITA Tomonori default: 23615d10b61SFUJITA Tomonori ret = -EINVAL; 23715d10b61SFUJITA Tomonori } 23815d10b61SFUJITA Tomonori break; 23915d10b61SFUJITA Tomonori default: 24015d10b61SFUJITA Tomonori ret = -EINVAL; 24115d10b61SFUJITA Tomonori } 24270e36eceSFUJITA Tomonori 24370e36eceSFUJITA Tomonori *rw = hdr->dout_xfer_len ? WRITE : READ; 24415d10b61SFUJITA Tomonori return ret; 2453d6392cfSJens Axboe } 2463d6392cfSJens Axboe 2473d6392cfSJens Axboe /* 24870e36eceSFUJITA Tomonori * map sg_io_v4 to a request. 2493d6392cfSJens Axboe */ 2503d6392cfSJens Axboe static struct request * 25170e36eceSFUJITA Tomonori bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) 2523d6392cfSJens Axboe { 253*165125e1SJens Axboe struct request_queue *q = bd->queue; 2542c9ecdf4SFUJITA Tomonori struct request *rq, *next_rq = NULL; 25525fd1643SJens Axboe int ret, rw; 25670e36eceSFUJITA Tomonori unsigned int dxfer_len; 25770e36eceSFUJITA Tomonori void *dxferp = NULL; 2583d6392cfSJens Axboe 25970e36eceSFUJITA Tomonori dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, 26070e36eceSFUJITA Tomonori hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, 26170e36eceSFUJITA Tomonori hdr->din_xfer_len); 2623d6392cfSJens Axboe 26370e36eceSFUJITA Tomonori ret = bsg_validate_sgv4_hdr(q, hdr, &rw); 2643d6392cfSJens Axboe if (ret) 2653d6392cfSJens Axboe return ERR_PTR(ret); 2663d6392cfSJens Axboe 2673d6392cfSJens Axboe /* 2683d6392cfSJens Axboe * map scatter-gather elements seperately and string them to request 2693d6392cfSJens Axboe */ 2703d6392cfSJens Axboe rq = blk_get_request(q, rw, GFP_KERNEL); 2712c9ecdf4SFUJITA Tomonori if (!rq) 2722c9ecdf4SFUJITA Tomonori return ERR_PTR(-ENOMEM); 27370e36eceSFUJITA Tomonori ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, 2743d6392cfSJens Axboe &bd->flags)); 2752c9ecdf4SFUJITA Tomonori if (ret) 2762c9ecdf4SFUJITA Tomonori goto out; 2772c9ecdf4SFUJITA Tomonori 2782c9ecdf4SFUJITA Tomonori if (rw == WRITE && hdr->din_xfer_len) { 2792c9ecdf4SFUJITA Tomonori if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) { 2802c9ecdf4SFUJITA Tomonori ret = -EOPNOTSUPP; 2812c9ecdf4SFUJITA Tomonori goto out; 2822c9ecdf4SFUJITA Tomonori } 2832c9ecdf4SFUJITA Tomonori 2842c9ecdf4SFUJITA Tomonori next_rq = blk_get_request(q, READ, GFP_KERNEL); 2852c9ecdf4SFUJITA Tomonori if (!next_rq) { 2862c9ecdf4SFUJITA Tomonori ret = -ENOMEM; 2872c9ecdf4SFUJITA Tomonori goto out; 2882c9ecdf4SFUJITA Tomonori } 2892c9ecdf4SFUJITA Tomonori rq->next_rq = next_rq; 2902c9ecdf4SFUJITA Tomonori 2912c9ecdf4SFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 2922c9ecdf4SFUJITA Tomonori ret = blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len); 2932c9ecdf4SFUJITA Tomonori if (ret) 2942c9ecdf4SFUJITA Tomonori goto out; 2953d6392cfSJens Axboe } 2963d6392cfSJens Axboe 29770e36eceSFUJITA Tomonori if (hdr->dout_xfer_len) { 29870e36eceSFUJITA Tomonori dxfer_len = hdr->dout_xfer_len; 29970e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->dout_xferp; 30070e36eceSFUJITA Tomonori } else if (hdr->din_xfer_len) { 30170e36eceSFUJITA Tomonori dxfer_len = hdr->din_xfer_len; 30270e36eceSFUJITA Tomonori dxferp = (void*)(unsigned long)hdr->din_xferp; 30370e36eceSFUJITA Tomonori } else 30470e36eceSFUJITA Tomonori dxfer_len = 0; 3053d6392cfSJens Axboe 30670e36eceSFUJITA Tomonori if (dxfer_len) { 30770e36eceSFUJITA Tomonori ret = blk_rq_map_user(q, rq, dxferp, dxfer_len); 3082c9ecdf4SFUJITA Tomonori if (ret) 3092c9ecdf4SFUJITA Tomonori goto out; 3103d6392cfSJens Axboe } 3113d6392cfSJens Axboe return rq; 3122c9ecdf4SFUJITA Tomonori out: 3132c9ecdf4SFUJITA Tomonori blk_put_request(rq); 3142c9ecdf4SFUJITA Tomonori if (next_rq) { 3152c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(next_rq->bio); 3162c9ecdf4SFUJITA Tomonori blk_put_request(next_rq); 3172c9ecdf4SFUJITA Tomonori } 3182c9ecdf4SFUJITA Tomonori return ERR_PTR(ret); 3193d6392cfSJens Axboe } 3203d6392cfSJens Axboe 3213d6392cfSJens Axboe /* 3223d6392cfSJens Axboe * async completion call-back from the block layer, when scsi/ide/whatever 3233d6392cfSJens Axboe * calls end_that_request_last() on a request 3243d6392cfSJens Axboe */ 3253d6392cfSJens Axboe static void bsg_rq_end_io(struct request *rq, int uptodate) 3263d6392cfSJens Axboe { 3273d6392cfSJens Axboe struct bsg_command *bc = rq->end_io_data; 3283d6392cfSJens Axboe struct bsg_device *bd = bc->bd; 3293d6392cfSJens Axboe unsigned long flags; 3303d6392cfSJens Axboe 3315309cb38SJens Axboe dprintk("%s: finished rq %p bc %p, bio %p stat %d\n", 3325309cb38SJens Axboe bd->name, rq, bc, bc->bio, uptodate); 3333d6392cfSJens Axboe 3343d6392cfSJens Axboe bc->hdr.duration = jiffies_to_msecs(jiffies - bc->hdr.duration); 3353d6392cfSJens Axboe 3363d6392cfSJens Axboe spin_lock_irqsave(&bd->lock, flags); 33725fd1643SJens Axboe list_move_tail(&bc->list, &bd->done_list); 33825fd1643SJens Axboe bd->done_cmds++; 3393d6392cfSJens Axboe spin_unlock_irqrestore(&bd->lock, flags); 34025fd1643SJens Axboe 34125fd1643SJens Axboe wake_up(&bd->wq_done); 3423d6392cfSJens Axboe } 3433d6392cfSJens Axboe 3443d6392cfSJens Axboe /* 3453d6392cfSJens Axboe * do final setup of a 'bc' and submit the matching 'rq' to the block 3463d6392cfSJens Axboe * layer for io 3473d6392cfSJens Axboe */ 348*165125e1SJens Axboe static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, 3493d6392cfSJens Axboe struct bsg_command *bc, struct request *rq) 3503d6392cfSJens Axboe { 3513d6392cfSJens Axboe rq->sense = bc->sense; 3523d6392cfSJens Axboe rq->sense_len = 0; 3533d6392cfSJens Axboe 3543d6392cfSJens Axboe /* 3553d6392cfSJens Axboe * add bc command to busy queue and submit rq for io 3563d6392cfSJens Axboe */ 3573d6392cfSJens Axboe bc->rq = rq; 3583d6392cfSJens Axboe bc->bio = rq->bio; 3592c9ecdf4SFUJITA Tomonori if (rq->next_rq) 3602c9ecdf4SFUJITA Tomonori bc->bidi_bio = rq->next_rq->bio; 3613d6392cfSJens Axboe bc->hdr.duration = jiffies; 3623d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3633d6392cfSJens Axboe list_add_tail(&bc->list, &bd->busy_list); 3643d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3653d6392cfSJens Axboe 3663d6392cfSJens Axboe dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); 3673d6392cfSJens Axboe 3683d6392cfSJens Axboe rq->end_io_data = bc; 369d351af01SFUJITA Tomonori blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io); 3703d6392cfSJens Axboe } 3713d6392cfSJens Axboe 37225fd1643SJens Axboe static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) 3733d6392cfSJens Axboe { 3743d6392cfSJens Axboe struct bsg_command *bc = NULL; 3753d6392cfSJens Axboe 3763d6392cfSJens Axboe spin_lock_irq(&bd->lock); 3773d6392cfSJens Axboe if (bd->done_cmds) { 37825fd1643SJens Axboe bc = list_entry(bd->done_list.next, struct bsg_command, list); 37925fd1643SJens Axboe list_del(&bc->list); 38025fd1643SJens Axboe bd->done_cmds--; 3813d6392cfSJens Axboe } 3823d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 3833d6392cfSJens Axboe 3843d6392cfSJens Axboe return bc; 3853d6392cfSJens Axboe } 3863d6392cfSJens Axboe 3873d6392cfSJens Axboe /* 3883d6392cfSJens Axboe * Get a finished command from the done list 3893d6392cfSJens Axboe */ 390e7d72173SFUJITA Tomonori static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd) 3913d6392cfSJens Axboe { 3923d6392cfSJens Axboe struct bsg_command *bc; 3933d6392cfSJens Axboe int ret; 3943d6392cfSJens Axboe 3953d6392cfSJens Axboe do { 3963d6392cfSJens Axboe bc = bsg_next_done_cmd(bd); 3973d6392cfSJens Axboe if (bc) 3983d6392cfSJens Axboe break; 3993d6392cfSJens Axboe 400e7d72173SFUJITA Tomonori if (!test_bit(BSG_F_BLOCK, &bd->flags)) { 401e7d72173SFUJITA Tomonori bc = ERR_PTR(-EAGAIN); 402e7d72173SFUJITA Tomonori break; 403e7d72173SFUJITA Tomonori } 404e7d72173SFUJITA Tomonori 405e7d72173SFUJITA Tomonori ret = wait_event_interruptible(bd->wq_done, bd->done_cmds); 4063d6392cfSJens Axboe if (ret) { 407e7d72173SFUJITA Tomonori bc = ERR_PTR(-ERESTARTSYS); 4083d6392cfSJens Axboe break; 4093d6392cfSJens Axboe } 4103d6392cfSJens Axboe } while (1); 4113d6392cfSJens Axboe 4123d6392cfSJens Axboe dprintk("%s: returning done %p\n", bd->name, bc); 4133d6392cfSJens Axboe 4143d6392cfSJens Axboe return bc; 4153d6392cfSJens Axboe } 4163d6392cfSJens Axboe 41770e36eceSFUJITA Tomonori static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, 4182c9ecdf4SFUJITA Tomonori struct bio *bio, struct bio *bidi_bio) 41970e36eceSFUJITA Tomonori { 42070e36eceSFUJITA Tomonori int ret = 0; 42170e36eceSFUJITA Tomonori 42270e36eceSFUJITA Tomonori dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); 42370e36eceSFUJITA Tomonori /* 42470e36eceSFUJITA Tomonori * fill in all the output members 42570e36eceSFUJITA Tomonori */ 42670e36eceSFUJITA Tomonori hdr->device_status = status_byte(rq->errors); 42770e36eceSFUJITA Tomonori hdr->transport_status = host_byte(rq->errors); 42870e36eceSFUJITA Tomonori hdr->driver_status = driver_byte(rq->errors); 42970e36eceSFUJITA Tomonori hdr->info = 0; 43070e36eceSFUJITA Tomonori if (hdr->device_status || hdr->transport_status || hdr->driver_status) 43170e36eceSFUJITA Tomonori hdr->info |= SG_INFO_CHECK; 43270e36eceSFUJITA Tomonori hdr->din_resid = rq->data_len; 43370e36eceSFUJITA Tomonori hdr->response_len = 0; 43470e36eceSFUJITA Tomonori 43570e36eceSFUJITA Tomonori if (rq->sense_len && hdr->response) { 43625fd1643SJens Axboe int len = min_t(unsigned int, hdr->max_response_len, 43770e36eceSFUJITA Tomonori rq->sense_len); 43870e36eceSFUJITA Tomonori 43970e36eceSFUJITA Tomonori ret = copy_to_user((void*)(unsigned long)hdr->response, 44070e36eceSFUJITA Tomonori rq->sense, len); 44170e36eceSFUJITA Tomonori if (!ret) 44270e36eceSFUJITA Tomonori hdr->response_len = len; 44370e36eceSFUJITA Tomonori else 44470e36eceSFUJITA Tomonori ret = -EFAULT; 44570e36eceSFUJITA Tomonori } 44670e36eceSFUJITA Tomonori 4472c9ecdf4SFUJITA Tomonori if (rq->next_rq) { 4482c9ecdf4SFUJITA Tomonori blk_rq_unmap_user(bidi_bio); 4492c9ecdf4SFUJITA Tomonori blk_put_request(rq->next_rq); 4502c9ecdf4SFUJITA Tomonori } 4512c9ecdf4SFUJITA Tomonori 45270e36eceSFUJITA Tomonori blk_rq_unmap_user(bio); 45370e36eceSFUJITA Tomonori blk_put_request(rq); 45470e36eceSFUJITA Tomonori 45570e36eceSFUJITA Tomonori return ret; 45670e36eceSFUJITA Tomonori } 45770e36eceSFUJITA Tomonori 4583d6392cfSJens Axboe static int bsg_complete_all_commands(struct bsg_device *bd) 4593d6392cfSJens Axboe { 4603d6392cfSJens Axboe struct bsg_command *bc; 4613d6392cfSJens Axboe int ret, tret; 4623d6392cfSJens Axboe 4633d6392cfSJens Axboe dprintk("%s: entered\n", bd->name); 4643d6392cfSJens Axboe 4653d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 4663d6392cfSJens Axboe 4673d6392cfSJens Axboe /* 4683d6392cfSJens Axboe * wait for all commands to complete 4693d6392cfSJens Axboe */ 4703d6392cfSJens Axboe ret = 0; 4713d6392cfSJens Axboe do { 47225fd1643SJens Axboe ret = bsg_io_schedule(bd); 4733d6392cfSJens Axboe /* 4743d6392cfSJens Axboe * look for -ENODATA specifically -- we'll sometimes get 4753d6392cfSJens Axboe * -ERESTARTSYS when we've taken a signal, but we can't 4763d6392cfSJens Axboe * return until we're done freeing the queue, so ignore 4773d6392cfSJens Axboe * it. The signal will get handled when we're done freeing 4783d6392cfSJens Axboe * the bsg_device. 4793d6392cfSJens Axboe */ 4803d6392cfSJens Axboe } while (ret != -ENODATA); 4813d6392cfSJens Axboe 4823d6392cfSJens Axboe /* 4833d6392cfSJens Axboe * discard done commands 4843d6392cfSJens Axboe */ 4853d6392cfSJens Axboe ret = 0; 4863d6392cfSJens Axboe do { 487e7d72173SFUJITA Tomonori spin_lock_irq(&bd->lock); 488e7d72173SFUJITA Tomonori if (!bd->queued_cmds) { 489e7d72173SFUJITA Tomonori spin_unlock_irq(&bd->lock); 4903d6392cfSJens Axboe break; 4913d6392cfSJens Axboe } 492efba1a31SFUJITA Tomonori spin_unlock_irq(&bd->lock); 4933d6392cfSJens Axboe 494e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 495e7d72173SFUJITA Tomonori if (IS_ERR(bc)) 496e7d72173SFUJITA Tomonori break; 497e7d72173SFUJITA Tomonori 4982c9ecdf4SFUJITA Tomonori tret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 4992c9ecdf4SFUJITA Tomonori bc->bidi_bio); 5003d6392cfSJens Axboe if (!ret) 5013d6392cfSJens Axboe ret = tret; 5023d6392cfSJens Axboe 5033d6392cfSJens Axboe bsg_free_command(bc); 5043d6392cfSJens Axboe } while (1); 5053d6392cfSJens Axboe 5063d6392cfSJens Axboe return ret; 5073d6392cfSJens Axboe } 5083d6392cfSJens Axboe 50925fd1643SJens Axboe static int 510e7d72173SFUJITA Tomonori __bsg_read(char __user *buf, size_t count, struct bsg_device *bd, 511e7d72173SFUJITA Tomonori const struct iovec *iov, ssize_t *bytes_read) 5123d6392cfSJens Axboe { 5133d6392cfSJens Axboe struct bsg_command *bc; 5143d6392cfSJens Axboe int nr_commands, ret; 5153d6392cfSJens Axboe 51670e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 5173d6392cfSJens Axboe return -EINVAL; 5183d6392cfSJens Axboe 5193d6392cfSJens Axboe ret = 0; 52070e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 5213d6392cfSJens Axboe while (nr_commands) { 522e7d72173SFUJITA Tomonori bc = bsg_get_done_cmd(bd); 5233d6392cfSJens Axboe if (IS_ERR(bc)) { 5243d6392cfSJens Axboe ret = PTR_ERR(bc); 5253d6392cfSJens Axboe break; 5263d6392cfSJens Axboe } 5273d6392cfSJens Axboe 5283d6392cfSJens Axboe /* 5293d6392cfSJens Axboe * this is the only case where we need to copy data back 5303d6392cfSJens Axboe * after completing the request. so do that here, 5313d6392cfSJens Axboe * bsg_complete_work() cannot do that for us 5323d6392cfSJens Axboe */ 5332c9ecdf4SFUJITA Tomonori ret = blk_complete_sgv4_hdr_rq(bc->rq, &bc->hdr, bc->bio, 5342c9ecdf4SFUJITA Tomonori bc->bidi_bio); 5353d6392cfSJens Axboe 53625fd1643SJens Axboe if (copy_to_user(buf, &bc->hdr, sizeof(bc->hdr))) 5373d6392cfSJens Axboe ret = -EFAULT; 5383d6392cfSJens Axboe 5393d6392cfSJens Axboe bsg_free_command(bc); 5403d6392cfSJens Axboe 5413d6392cfSJens Axboe if (ret) 5423d6392cfSJens Axboe break; 5433d6392cfSJens Axboe 54470e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 54570e36eceSFUJITA Tomonori *bytes_read += sizeof(struct sg_io_v4); 5463d6392cfSJens Axboe nr_commands--; 5473d6392cfSJens Axboe } 5483d6392cfSJens Axboe 5493d6392cfSJens Axboe return ret; 5503d6392cfSJens Axboe } 5513d6392cfSJens Axboe 5523d6392cfSJens Axboe static inline void bsg_set_block(struct bsg_device *bd, struct file *file) 5533d6392cfSJens Axboe { 5543d6392cfSJens Axboe if (file->f_flags & O_NONBLOCK) 5553d6392cfSJens Axboe clear_bit(BSG_F_BLOCK, &bd->flags); 5563d6392cfSJens Axboe else 5573d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 5583d6392cfSJens Axboe } 5593d6392cfSJens Axboe 5603d6392cfSJens Axboe static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) 5613d6392cfSJens Axboe { 5623d6392cfSJens Axboe if (file->f_mode & FMODE_WRITE) 5633d6392cfSJens Axboe set_bit(BSG_F_WRITE_PERM, &bd->flags); 5643d6392cfSJens Axboe else 5653d6392cfSJens Axboe clear_bit(BSG_F_WRITE_PERM, &bd->flags); 5663d6392cfSJens Axboe } 5673d6392cfSJens Axboe 56825fd1643SJens Axboe /* 56925fd1643SJens Axboe * Check if the error is a "real" error that we should return. 57025fd1643SJens Axboe */ 5713d6392cfSJens Axboe static inline int err_block_err(int ret) 5723d6392cfSJens Axboe { 5733d6392cfSJens Axboe if (ret && ret != -ENOSPC && ret != -ENODATA && ret != -EAGAIN) 5743d6392cfSJens Axboe return 1; 5753d6392cfSJens Axboe 5763d6392cfSJens Axboe return 0; 5773d6392cfSJens Axboe } 5783d6392cfSJens Axboe 5793d6392cfSJens Axboe static ssize_t 5803d6392cfSJens Axboe bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 5813d6392cfSJens Axboe { 5823d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 5833d6392cfSJens Axboe int ret; 5843d6392cfSJens Axboe ssize_t bytes_read; 5853d6392cfSJens Axboe 5869e69fbb5SFUJITA Tomonori dprintk("%s: read %Zd bytes\n", bd->name, count); 5873d6392cfSJens Axboe 5883d6392cfSJens Axboe bsg_set_block(bd, file); 5893d6392cfSJens Axboe bytes_read = 0; 590e7d72173SFUJITA Tomonori ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 5913d6392cfSJens Axboe *ppos = bytes_read; 5923d6392cfSJens Axboe 5933d6392cfSJens Axboe if (!bytes_read || (bytes_read && err_block_err(ret))) 5943d6392cfSJens Axboe bytes_read = ret; 5953d6392cfSJens Axboe 5963d6392cfSJens Axboe return bytes_read; 5973d6392cfSJens Axboe } 5983d6392cfSJens Axboe 59925fd1643SJens Axboe static int __bsg_write(struct bsg_device *bd, const char __user *buf, 60025fd1643SJens Axboe size_t count, ssize_t *bytes_written) 6013d6392cfSJens Axboe { 6023d6392cfSJens Axboe struct bsg_command *bc; 6033d6392cfSJens Axboe struct request *rq; 6043d6392cfSJens Axboe int ret, nr_commands; 6053d6392cfSJens Axboe 60670e36eceSFUJITA Tomonori if (count % sizeof(struct sg_io_v4)) 6073d6392cfSJens Axboe return -EINVAL; 6083d6392cfSJens Axboe 60970e36eceSFUJITA Tomonori nr_commands = count / sizeof(struct sg_io_v4); 6103d6392cfSJens Axboe rq = NULL; 6113d6392cfSJens Axboe bc = NULL; 6123d6392cfSJens Axboe ret = 0; 6133d6392cfSJens Axboe while (nr_commands) { 614*165125e1SJens Axboe struct request_queue *q = bd->queue; 6153d6392cfSJens Axboe 616e7d72173SFUJITA Tomonori bc = bsg_alloc_command(bd); 6173d6392cfSJens Axboe if (IS_ERR(bc)) { 6183d6392cfSJens Axboe ret = PTR_ERR(bc); 6193d6392cfSJens Axboe bc = NULL; 6203d6392cfSJens Axboe break; 6213d6392cfSJens Axboe } 6223d6392cfSJens Axboe 62370e36eceSFUJITA Tomonori bc->uhdr = (struct sg_io_v4 __user *) buf; 6243d6392cfSJens Axboe if (copy_from_user(&bc->hdr, buf, sizeof(bc->hdr))) { 6253d6392cfSJens Axboe ret = -EFAULT; 6263d6392cfSJens Axboe break; 6273d6392cfSJens Axboe } 6283d6392cfSJens Axboe 6293d6392cfSJens Axboe /* 6303d6392cfSJens Axboe * get a request, fill in the blanks, and add to request queue 6313d6392cfSJens Axboe */ 63270e36eceSFUJITA Tomonori rq = bsg_map_hdr(bd, &bc->hdr); 6333d6392cfSJens Axboe if (IS_ERR(rq)) { 6343d6392cfSJens Axboe ret = PTR_ERR(rq); 6353d6392cfSJens Axboe rq = NULL; 6363d6392cfSJens Axboe break; 6373d6392cfSJens Axboe } 6383d6392cfSJens Axboe 6393d6392cfSJens Axboe bsg_add_command(bd, q, bc, rq); 6403d6392cfSJens Axboe bc = NULL; 6413d6392cfSJens Axboe rq = NULL; 6423d6392cfSJens Axboe nr_commands--; 64370e36eceSFUJITA Tomonori buf += sizeof(struct sg_io_v4); 64425fd1643SJens Axboe *bytes_written += sizeof(struct sg_io_v4); 6453d6392cfSJens Axboe } 6463d6392cfSJens Axboe 6473d6392cfSJens Axboe if (bc) 6483d6392cfSJens Axboe bsg_free_command(bc); 6493d6392cfSJens Axboe 6503d6392cfSJens Axboe return ret; 6513d6392cfSJens Axboe } 6523d6392cfSJens Axboe 6533d6392cfSJens Axboe static ssize_t 6543d6392cfSJens Axboe bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 6553d6392cfSJens Axboe { 6563d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 65725fd1643SJens Axboe ssize_t bytes_written; 6583d6392cfSJens Axboe int ret; 6593d6392cfSJens Axboe 6609e69fbb5SFUJITA Tomonori dprintk("%s: write %Zd bytes\n", bd->name, count); 6613d6392cfSJens Axboe 6623d6392cfSJens Axboe bsg_set_block(bd, file); 6633d6392cfSJens Axboe bsg_set_write_perm(bd, file); 6643d6392cfSJens Axboe 66525fd1643SJens Axboe bytes_written = 0; 66625fd1643SJens Axboe ret = __bsg_write(bd, buf, count, &bytes_written); 66725fd1643SJens Axboe *ppos = bytes_written; 6683d6392cfSJens Axboe 6693d6392cfSJens Axboe /* 6703d6392cfSJens Axboe * return bytes written on non-fatal errors 6713d6392cfSJens Axboe */ 67225fd1643SJens Axboe if (!bytes_written || (bytes_written && err_block_err(ret))) 67325fd1643SJens Axboe bytes_written = ret; 6743d6392cfSJens Axboe 67525fd1643SJens Axboe dprintk("%s: returning %Zd\n", bd->name, bytes_written); 67625fd1643SJens Axboe return bytes_written; 6773d6392cfSJens Axboe } 6783d6392cfSJens Axboe 6793d6392cfSJens Axboe static struct bsg_device *bsg_alloc_device(void) 6803d6392cfSJens Axboe { 6813d6392cfSJens Axboe struct bsg_device *bd; 6823d6392cfSJens Axboe 6833d6392cfSJens Axboe bd = kzalloc(sizeof(struct bsg_device), GFP_KERNEL); 6843d6392cfSJens Axboe if (unlikely(!bd)) 6853d6392cfSJens Axboe return NULL; 6863d6392cfSJens Axboe 6873d6392cfSJens Axboe spin_lock_init(&bd->lock); 6883d6392cfSJens Axboe 6895309cb38SJens Axboe bd->max_queue = BSG_DEFAULT_CMDS; 6903d6392cfSJens Axboe 6913d6392cfSJens Axboe INIT_LIST_HEAD(&bd->busy_list); 6923d6392cfSJens Axboe INIT_LIST_HEAD(&bd->done_list); 6933d6392cfSJens Axboe INIT_HLIST_NODE(&bd->dev_list); 6943d6392cfSJens Axboe 6953d6392cfSJens Axboe init_waitqueue_head(&bd->wq_free); 6963d6392cfSJens Axboe init_waitqueue_head(&bd->wq_done); 6973d6392cfSJens Axboe return bd; 6983d6392cfSJens Axboe } 6993d6392cfSJens Axboe 7003d6392cfSJens Axboe static int bsg_put_device(struct bsg_device *bd) 7013d6392cfSJens Axboe { 7023d6392cfSJens Axboe int ret = 0; 7033d6392cfSJens Axboe 7043d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7053d6392cfSJens Axboe 7063d6392cfSJens Axboe if (!atomic_dec_and_test(&bd->ref_count)) 7073d6392cfSJens Axboe goto out; 7083d6392cfSJens Axboe 7093d6392cfSJens Axboe dprintk("%s: tearing down\n", bd->name); 7103d6392cfSJens Axboe 7113d6392cfSJens Axboe /* 7123d6392cfSJens Axboe * close can always block 7133d6392cfSJens Axboe */ 7143d6392cfSJens Axboe set_bit(BSG_F_BLOCK, &bd->flags); 7153d6392cfSJens Axboe 7163d6392cfSJens Axboe /* 7173d6392cfSJens Axboe * correct error detection baddies here again. it's the responsibility 7183d6392cfSJens Axboe * of the app to properly reap commands before close() if it wants 7193d6392cfSJens Axboe * fool-proof error detection 7203d6392cfSJens Axboe */ 7213d6392cfSJens Axboe ret = bsg_complete_all_commands(bd); 7223d6392cfSJens Axboe 7233d6392cfSJens Axboe blk_put_queue(bd->queue); 7243d6392cfSJens Axboe hlist_del(&bd->dev_list); 7255309cb38SJens Axboe kfree(bd); 7263d6392cfSJens Axboe out: 7273d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7283d6392cfSJens Axboe return ret; 7293d6392cfSJens Axboe } 7303d6392cfSJens Axboe 7313d6392cfSJens Axboe static struct bsg_device *bsg_add_device(struct inode *inode, 732d351af01SFUJITA Tomonori struct request_queue *rq, 7333d6392cfSJens Axboe struct file *file) 7343d6392cfSJens Axboe { 73525fd1643SJens Axboe struct bsg_device *bd; 7363d6392cfSJens Axboe #ifdef BSG_DEBUG 7373d6392cfSJens Axboe unsigned char buf[32]; 7383d6392cfSJens Axboe #endif 7393d6392cfSJens Axboe 7403d6392cfSJens Axboe bd = bsg_alloc_device(); 7413d6392cfSJens Axboe if (!bd) 7423d6392cfSJens Axboe return ERR_PTR(-ENOMEM); 7433d6392cfSJens Axboe 744d351af01SFUJITA Tomonori bd->queue = rq; 745d351af01SFUJITA Tomonori kobject_get(&rq->kobj); 7463d6392cfSJens Axboe bsg_set_block(bd, file); 7473d6392cfSJens Axboe 7483d6392cfSJens Axboe atomic_set(&bd->ref_count, 1); 7493d6392cfSJens Axboe bd->minor = iminor(inode); 7503d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7511c1133e1SFUJITA Tomonori hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor)); 7523d6392cfSJens Axboe 753d351af01SFUJITA Tomonori strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); 7543d6392cfSJens Axboe dprintk("bound to <%s>, max queue %d\n", 7559e69fbb5SFUJITA Tomonori format_dev_t(buf, inode->i_rdev), bd->max_queue); 7563d6392cfSJens Axboe 7573d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7583d6392cfSJens Axboe return bd; 7593d6392cfSJens Axboe } 7603d6392cfSJens Axboe 7613d6392cfSJens Axboe static struct bsg_device *__bsg_get_device(int minor) 7623d6392cfSJens Axboe { 7633d6392cfSJens Axboe struct bsg_device *bd = NULL; 7643d6392cfSJens Axboe struct hlist_node *entry; 7653d6392cfSJens Axboe 7663d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7673d6392cfSJens Axboe 7681c1133e1SFUJITA Tomonori hlist_for_each(entry, bsg_dev_idx_hash(minor)) { 7693d6392cfSJens Axboe bd = hlist_entry(entry, struct bsg_device, dev_list); 7703d6392cfSJens Axboe if (bd->minor == minor) { 7713d6392cfSJens Axboe atomic_inc(&bd->ref_count); 7723d6392cfSJens Axboe break; 7733d6392cfSJens Axboe } 7743d6392cfSJens Axboe 7753d6392cfSJens Axboe bd = NULL; 7763d6392cfSJens Axboe } 7773d6392cfSJens Axboe 7783d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 7793d6392cfSJens Axboe return bd; 7803d6392cfSJens Axboe } 7813d6392cfSJens Axboe 7823d6392cfSJens Axboe static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) 7833d6392cfSJens Axboe { 7843d6392cfSJens Axboe struct bsg_device *bd = __bsg_get_device(iminor(inode)); 7853d6392cfSJens Axboe struct bsg_class_device *bcd, *__bcd; 7863d6392cfSJens Axboe 7873d6392cfSJens Axboe if (bd) 7883d6392cfSJens Axboe return bd; 7893d6392cfSJens Axboe 7903d6392cfSJens Axboe /* 7913d6392cfSJens Axboe * find the class device 7923d6392cfSJens Axboe */ 7933d6392cfSJens Axboe bcd = NULL; 7943d6392cfSJens Axboe mutex_lock(&bsg_mutex); 7953d6392cfSJens Axboe list_for_each_entry(__bcd, &bsg_class_list, list) { 7963d6392cfSJens Axboe if (__bcd->minor == iminor(inode)) { 7973d6392cfSJens Axboe bcd = __bcd; 7983d6392cfSJens Axboe break; 7993d6392cfSJens Axboe } 8003d6392cfSJens Axboe } 8013d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 8023d6392cfSJens Axboe 8033d6392cfSJens Axboe if (!bcd) 8043d6392cfSJens Axboe return ERR_PTR(-ENODEV); 8053d6392cfSJens Axboe 806d351af01SFUJITA Tomonori return bsg_add_device(inode, bcd->queue, file); 8073d6392cfSJens Axboe } 8083d6392cfSJens Axboe 8093d6392cfSJens Axboe static int bsg_open(struct inode *inode, struct file *file) 8103d6392cfSJens Axboe { 8113d6392cfSJens Axboe struct bsg_device *bd = bsg_get_device(inode, file); 8123d6392cfSJens Axboe 8133d6392cfSJens Axboe if (IS_ERR(bd)) 8143d6392cfSJens Axboe return PTR_ERR(bd); 8153d6392cfSJens Axboe 8163d6392cfSJens Axboe file->private_data = bd; 8173d6392cfSJens Axboe return 0; 8183d6392cfSJens Axboe } 8193d6392cfSJens Axboe 8203d6392cfSJens Axboe static int bsg_release(struct inode *inode, struct file *file) 8213d6392cfSJens Axboe { 8223d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8233d6392cfSJens Axboe 8243d6392cfSJens Axboe file->private_data = NULL; 8253d6392cfSJens Axboe return bsg_put_device(bd); 8263d6392cfSJens Axboe } 8273d6392cfSJens Axboe 8283d6392cfSJens Axboe static unsigned int bsg_poll(struct file *file, poll_table *wait) 8293d6392cfSJens Axboe { 8303d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8313d6392cfSJens Axboe unsigned int mask = 0; 8323d6392cfSJens Axboe 8333d6392cfSJens Axboe poll_wait(file, &bd->wq_done, wait); 8343d6392cfSJens Axboe poll_wait(file, &bd->wq_free, wait); 8353d6392cfSJens Axboe 8363d6392cfSJens Axboe spin_lock_irq(&bd->lock); 8373d6392cfSJens Axboe if (!list_empty(&bd->done_list)) 8383d6392cfSJens Axboe mask |= POLLIN | POLLRDNORM; 8393d6392cfSJens Axboe if (bd->queued_cmds >= bd->max_queue) 8403d6392cfSJens Axboe mask |= POLLOUT; 8413d6392cfSJens Axboe spin_unlock_irq(&bd->lock); 8423d6392cfSJens Axboe 8433d6392cfSJens Axboe return mask; 8443d6392cfSJens Axboe } 8453d6392cfSJens Axboe 84625fd1643SJens Axboe static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 8473d6392cfSJens Axboe { 8483d6392cfSJens Axboe struct bsg_device *bd = file->private_data; 8493d6392cfSJens Axboe int __user *uarg = (int __user *) arg; 8503d6392cfSJens Axboe 8513d6392cfSJens Axboe switch (cmd) { 8523d6392cfSJens Axboe /* 8533d6392cfSJens Axboe * our own ioctls 8543d6392cfSJens Axboe */ 8553d6392cfSJens Axboe case SG_GET_COMMAND_Q: 8563d6392cfSJens Axboe return put_user(bd->max_queue, uarg); 8573d6392cfSJens Axboe case SG_SET_COMMAND_Q: { 8583d6392cfSJens Axboe int queue; 8593d6392cfSJens Axboe 8603d6392cfSJens Axboe if (get_user(queue, uarg)) 8613d6392cfSJens Axboe return -EFAULT; 8625309cb38SJens Axboe if (queue < 1) 8633d6392cfSJens Axboe return -EINVAL; 8643d6392cfSJens Axboe 8655309cb38SJens Axboe spin_lock_irq(&bd->lock); 8663d6392cfSJens Axboe bd->max_queue = queue; 8675309cb38SJens Axboe spin_unlock_irq(&bd->lock); 8683d6392cfSJens Axboe return 0; 8693d6392cfSJens Axboe } 8703d6392cfSJens Axboe 8713d6392cfSJens Axboe /* 8723d6392cfSJens Axboe * SCSI/sg ioctls 8733d6392cfSJens Axboe */ 8743d6392cfSJens Axboe case SG_GET_VERSION_NUM: 8753d6392cfSJens Axboe case SCSI_IOCTL_GET_IDLUN: 8763d6392cfSJens Axboe case SCSI_IOCTL_GET_BUS_NUMBER: 8773d6392cfSJens Axboe case SG_SET_TIMEOUT: 8783d6392cfSJens Axboe case SG_GET_TIMEOUT: 8793d6392cfSJens Axboe case SG_GET_RESERVED_SIZE: 8803d6392cfSJens Axboe case SG_SET_RESERVED_SIZE: 8813d6392cfSJens Axboe case SG_EMULATED_HOST: 8823d6392cfSJens Axboe case SCSI_IOCTL_SEND_COMMAND: { 8833d6392cfSJens Axboe void __user *uarg = (void __user *) arg; 884d351af01SFUJITA Tomonori return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); 8853d6392cfSJens Axboe } 88610e8855bSFUJITA Tomonori case SG_IO: { 88710e8855bSFUJITA Tomonori struct request *rq; 8882c9ecdf4SFUJITA Tomonori struct bio *bio, *bidi_bio = NULL; 88910e8855bSFUJITA Tomonori struct sg_io_v4 hdr; 89010e8855bSFUJITA Tomonori 89110e8855bSFUJITA Tomonori if (copy_from_user(&hdr, uarg, sizeof(hdr))) 89210e8855bSFUJITA Tomonori return -EFAULT; 89310e8855bSFUJITA Tomonori 89410e8855bSFUJITA Tomonori rq = bsg_map_hdr(bd, &hdr); 89510e8855bSFUJITA Tomonori if (IS_ERR(rq)) 89610e8855bSFUJITA Tomonori return PTR_ERR(rq); 89710e8855bSFUJITA Tomonori 89810e8855bSFUJITA Tomonori bio = rq->bio; 8992c9ecdf4SFUJITA Tomonori if (rq->next_rq) 9002c9ecdf4SFUJITA Tomonori bidi_bio = rq->next_rq->bio; 901d351af01SFUJITA Tomonori blk_execute_rq(bd->queue, NULL, rq, 0); 9022c9ecdf4SFUJITA Tomonori blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); 90310e8855bSFUJITA Tomonori 90410e8855bSFUJITA Tomonori if (copy_to_user(uarg, &hdr, sizeof(hdr))) 90510e8855bSFUJITA Tomonori return -EFAULT; 906b711afa6SJens Axboe 90710e8855bSFUJITA Tomonori return 0; 90810e8855bSFUJITA Tomonori } 9093d6392cfSJens Axboe /* 9103d6392cfSJens Axboe * block device ioctls 9113d6392cfSJens Axboe */ 9123d6392cfSJens Axboe default: 9133d6392cfSJens Axboe #if 0 9143d6392cfSJens Axboe return ioctl_by_bdev(bd->bdev, cmd, arg); 9153d6392cfSJens Axboe #else 9163d6392cfSJens Axboe return -ENOTTY; 9173d6392cfSJens Axboe #endif 9183d6392cfSJens Axboe } 9193d6392cfSJens Axboe } 9203d6392cfSJens Axboe 9213d6392cfSJens Axboe static struct file_operations bsg_fops = { 9223d6392cfSJens Axboe .read = bsg_read, 9233d6392cfSJens Axboe .write = bsg_write, 9243d6392cfSJens Axboe .poll = bsg_poll, 9253d6392cfSJens Axboe .open = bsg_open, 9263d6392cfSJens Axboe .release = bsg_release, 92725fd1643SJens Axboe .unlocked_ioctl = bsg_ioctl, 9283d6392cfSJens Axboe .owner = THIS_MODULE, 9293d6392cfSJens Axboe }; 9303d6392cfSJens Axboe 931d351af01SFUJITA Tomonori void bsg_unregister_queue(struct request_queue *q) 9323d6392cfSJens Axboe { 933d351af01SFUJITA Tomonori struct bsg_class_device *bcd = &q->bsg_dev; 9343d6392cfSJens Axboe 935df468820SFUJITA Tomonori if (!bcd->class_dev) 936df468820SFUJITA Tomonori return; 9373d6392cfSJens Axboe 9383d6392cfSJens Axboe mutex_lock(&bsg_mutex); 939d351af01SFUJITA Tomonori sysfs_remove_link(&q->kobj, "bsg"); 94039dca558SJames Bottomley class_device_unregister(bcd->class_dev); 94139dca558SJames Bottomley put_device(bcd->dev); 9423d6392cfSJens Axboe bcd->class_dev = NULL; 94339dca558SJames Bottomley bcd->dev = NULL; 9443d6392cfSJens Axboe list_del_init(&bcd->list); 945292b7f27SFUJITA Tomonori bsg_device_nr--; 9463d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 9473d6392cfSJens Axboe } 9484cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_unregister_queue); 9493d6392cfSJens Axboe 95039dca558SJames Bottomley int bsg_register_queue(struct request_queue *q, struct device *gdev, 95139dca558SJames Bottomley const char *name) 9523d6392cfSJens Axboe { 953292b7f27SFUJITA Tomonori struct bsg_class_device *bcd, *__bcd; 9543d6392cfSJens Axboe dev_t dev; 955292b7f27SFUJITA Tomonori int ret = -EMFILE; 9564e2872d6SFUJITA Tomonori struct class_device *class_dev = NULL; 95739dca558SJames Bottomley const char *devname; 95839dca558SJames Bottomley 95939dca558SJames Bottomley if (name) 96039dca558SJames Bottomley devname = name; 96139dca558SJames Bottomley else 96239dca558SJames Bottomley devname = gdev->bus_id; 9633d6392cfSJens Axboe 9643d6392cfSJens Axboe /* 9653d6392cfSJens Axboe * we need a proper transport to send commands, not a stacked device 9663d6392cfSJens Axboe */ 9673d6392cfSJens Axboe if (!q->request_fn) 9683d6392cfSJens Axboe return 0; 9693d6392cfSJens Axboe 970d351af01SFUJITA Tomonori bcd = &q->bsg_dev; 9713d6392cfSJens Axboe memset(bcd, 0, sizeof(*bcd)); 9723d6392cfSJens Axboe INIT_LIST_HEAD(&bcd->list); 9733d6392cfSJens Axboe 9743d6392cfSJens Axboe mutex_lock(&bsg_mutex); 975292b7f27SFUJITA Tomonori if (bsg_device_nr == BSG_MAX_DEVS) { 976292b7f27SFUJITA Tomonori printk(KERN_ERR "bsg: too many bsg devices\n"); 977292b7f27SFUJITA Tomonori goto err; 978292b7f27SFUJITA Tomonori } 979292b7f27SFUJITA Tomonori 980292b7f27SFUJITA Tomonori retry: 981292b7f27SFUJITA Tomonori list_for_each_entry(__bcd, &bsg_class_list, list) { 982292b7f27SFUJITA Tomonori if (__bcd->minor == bsg_minor_idx) { 983292b7f27SFUJITA Tomonori bsg_minor_idx++; 984292b7f27SFUJITA Tomonori if (bsg_minor_idx == BSG_MAX_DEVS) 985292b7f27SFUJITA Tomonori bsg_minor_idx = 0; 986292b7f27SFUJITA Tomonori goto retry; 987292b7f27SFUJITA Tomonori } 988292b7f27SFUJITA Tomonori } 989292b7f27SFUJITA Tomonori 990292b7f27SFUJITA Tomonori bcd->minor = bsg_minor_idx++; 991292b7f27SFUJITA Tomonori if (bsg_minor_idx == BSG_MAX_DEVS) 992292b7f27SFUJITA Tomonori bsg_minor_idx = 0; 993292b7f27SFUJITA Tomonori 994d351af01SFUJITA Tomonori bcd->queue = q; 99539dca558SJames Bottomley bcd->dev = get_device(gdev); 99646f6ef4aSJens Axboe dev = MKDEV(bsg_major, bcd->minor); 99739dca558SJames Bottomley class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s", 99839dca558SJames Bottomley devname); 9994e2872d6SFUJITA Tomonori if (IS_ERR(class_dev)) { 10004e2872d6SFUJITA Tomonori ret = PTR_ERR(class_dev); 100139dca558SJames Bottomley goto err_put; 10024e2872d6SFUJITA Tomonori } 10034e2872d6SFUJITA Tomonori bcd->class_dev = class_dev; 10044e2872d6SFUJITA Tomonori 1005abce891aSLinus Torvalds if (q->kobj.sd) { 10064e2872d6SFUJITA Tomonori ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); 10074e2872d6SFUJITA Tomonori if (ret) 10086826ee4fSJames Bottomley goto err_unregister; 10094e2872d6SFUJITA Tomonori } 10104e2872d6SFUJITA Tomonori 10113d6392cfSJens Axboe list_add_tail(&bcd->list, &bsg_class_list); 1012292b7f27SFUJITA Tomonori bsg_device_nr++; 10134e2872d6SFUJITA Tomonori 10143d6392cfSJens Axboe mutex_unlock(&bsg_mutex); 10153d6392cfSJens Axboe return 0; 10166826ee4fSJames Bottomley 10176826ee4fSJames Bottomley err_unregister: 10186826ee4fSJames Bottomley class_device_unregister(class_dev); 101939dca558SJames Bottomley err_put: 102039dca558SJames Bottomley put_device(gdev); 1021264a0472SJens Axboe err: 1022264a0472SJens Axboe mutex_unlock(&bsg_mutex); 10234e2872d6SFUJITA Tomonori return ret; 10243d6392cfSJens Axboe } 10254cf0723aSFUJITA Tomonori EXPORT_SYMBOL_GPL(bsg_register_queue); 10263d6392cfSJens Axboe 1027292b7f27SFUJITA Tomonori static struct cdev bsg_cdev = { 1028292b7f27SFUJITA Tomonori .kobj = {.name = "bsg", }, 1029292b7f27SFUJITA Tomonori .owner = THIS_MODULE, 1030292b7f27SFUJITA Tomonori }; 1031292b7f27SFUJITA Tomonori 10323d6392cfSJens Axboe static int __init bsg_init(void) 10333d6392cfSJens Axboe { 10343d6392cfSJens Axboe int ret, i; 103546f6ef4aSJens Axboe dev_t devid; 10363d6392cfSJens Axboe 10375309cb38SJens Axboe bsg_cmd_cachep = kmem_cache_create("bsg_cmd", 103820c2df83SPaul Mundt sizeof(struct bsg_command), 0, 0, NULL); 10395309cb38SJens Axboe if (!bsg_cmd_cachep) { 10405309cb38SJens Axboe printk(KERN_ERR "bsg: failed creating slab cache\n"); 10415309cb38SJens Axboe return -ENOMEM; 10425309cb38SJens Axboe } 10435309cb38SJens Axboe 104425fd1643SJens Axboe for (i = 0; i < BSG_LIST_ARRAY_SIZE; i++) 10453d6392cfSJens Axboe INIT_HLIST_HEAD(&bsg_device_list[i]); 10463d6392cfSJens Axboe 10473d6392cfSJens Axboe bsg_class = class_create(THIS_MODULE, "bsg"); 10485309cb38SJens Axboe if (IS_ERR(bsg_class)) { 10499b9f770cSFUJITA Tomonori ret = PTR_ERR(bsg_class); 10509b9f770cSFUJITA Tomonori goto destroy_kmemcache; 10515309cb38SJens Axboe } 10523d6392cfSJens Axboe 105346f6ef4aSJens Axboe ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg"); 10549b9f770cSFUJITA Tomonori if (ret) 10559b9f770cSFUJITA Tomonori goto destroy_bsg_class; 10563d6392cfSJens Axboe 105746f6ef4aSJens Axboe bsg_major = MAJOR(devid); 105846f6ef4aSJens Axboe 1059292b7f27SFUJITA Tomonori cdev_init(&bsg_cdev, &bsg_fops); 106046f6ef4aSJens Axboe ret = cdev_add(&bsg_cdev, MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10619b9f770cSFUJITA Tomonori if (ret) 10629b9f770cSFUJITA Tomonori goto unregister_chrdev; 1063292b7f27SFUJITA Tomonori 10640ed081ceSFUJITA Tomonori printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION 10650ed081ceSFUJITA Tomonori " loaded (major %d)\n", bsg_major); 10663d6392cfSJens Axboe return 0; 10679b9f770cSFUJITA Tomonori unregister_chrdev: 10689b9f770cSFUJITA Tomonori unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); 10699b9f770cSFUJITA Tomonori destroy_bsg_class: 10709b9f770cSFUJITA Tomonori class_destroy(bsg_class); 10719b9f770cSFUJITA Tomonori destroy_kmemcache: 10729b9f770cSFUJITA Tomonori kmem_cache_destroy(bsg_cmd_cachep); 10739b9f770cSFUJITA Tomonori return ret; 10743d6392cfSJens Axboe } 10753d6392cfSJens Axboe 10763d6392cfSJens Axboe MODULE_AUTHOR("Jens Axboe"); 10770ed081ceSFUJITA Tomonori MODULE_DESCRIPTION(BSG_DESCRIPTION); 10783d6392cfSJens Axboe MODULE_LICENSE("GPL"); 10793d6392cfSJens Axboe 10804e2872d6SFUJITA Tomonori device_initcall(bsg_init); 1081