Blame view

block/bsg.c 12.4 KB
3d6392cfb   Jens Axboe   bsg: support for ...
1
  /*
0c6a89ba6   FUJITA Tomonori   [SCSI] bsg: updat...
2
   * bsg.c - block layer implementation of the sg v4 interface
3d6392cfb   Jens Axboe   bsg: support for ...
3
4
5
6
7
8
9
10
11
   *
   * Copyright (C) 2004 Jens Axboe <axboe@suse.de> SUSE Labs
   * Copyright (C) 2004 Peter M. Jones <pjones@redhat.com>
   *
   *  This file is subject to the terms and conditions of the GNU General Public
   *  License version 2.  See the file "COPYING" in the main directory of this
   *  archive for more details.
   *
   */
3d6392cfb   Jens Axboe   bsg: support for ...
12
13
14
15
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/file.h>
  #include <linux/blkdev.h>
3d6392cfb   Jens Axboe   bsg: support for ...
16
  #include <linux/cdev.h>
ad5ebd2fa   Randy Dunlap   block: jiffies fixes
17
  #include <linux/jiffies.h>
3d6392cfb   Jens Axboe   bsg: support for ...
18
  #include <linux/percpu.h>
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
19
  #include <linux/idr.h>
3d6392cfb   Jens Axboe   bsg: support for ...
20
  #include <linux/bsg.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
21
  #include <linux/slab.h>
3d6392cfb   Jens Axboe   bsg: support for ...
22
23
24
25
  
  #include <scsi/scsi.h>
  #include <scsi/scsi_ioctl.h>
  #include <scsi/scsi_cmnd.h>
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
26
27
  #include <scsi/scsi_device.h>
  #include <scsi/scsi_driver.h>
3d6392cfb   Jens Axboe   bsg: support for ...
28
  #include <scsi/sg.h>
0ed081ce2   FUJITA Tomonori   bsg: minor cleanup
29
30
  #define BSG_DESCRIPTION	"Block layer SCSI generic (bsg) driver"
  #define BSG_VERSION	"0.4"
3d6392cfb   Jens Axboe   bsg: support for ...
31

3124b65da   Johannes Thumshirn   bsg: use pr_debug...
32
33
  #define bsg_dbg(bd, fmt, ...) \
  	pr_debug("%s: " fmt, (bd)->name, ##__VA_ARGS__)
3d6392cfb   Jens Axboe   bsg: support for ...
34
  struct bsg_device {
165125e1e   Jens Axboe   [BLOCK] Get rid o...
35
  	struct request_queue *queue;
3d6392cfb   Jens Axboe   bsg: support for ...
36
  	spinlock_t lock;
3d6392cfb   Jens Axboe   bsg: support for ...
37
  	struct hlist_node dev_list;
db193954e   John Pittman   block: bsg: move ...
38
  	refcount_t ref_count;
3ada8b7e9   Kay Sievers   block: struct dev...
39
  	char name[20];
3d6392cfb   Jens Axboe   bsg: support for ...
40
  	int max_queue;
3d6392cfb   Jens Axboe   bsg: support for ...
41
  };
5309cb38d   Jens Axboe   Add queue resizin...
42
  #define BSG_DEFAULT_CMDS	64
292b7f271   FUJITA Tomonori   improve bsg devic...
43
  #define BSG_MAX_DEVS		32768
3d6392cfb   Jens Axboe   bsg: support for ...
44

3d6392cfb   Jens Axboe   bsg: support for ...
45
  static DEFINE_MUTEX(bsg_mutex);
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
46
  static DEFINE_IDR(bsg_minor_idr);
3d6392cfb   Jens Axboe   bsg: support for ...
47

25fd16430   Jens Axboe   bsg: address vari...
48
  #define BSG_LIST_ARRAY_SIZE	8
25fd16430   Jens Axboe   bsg: address vari...
49
  static struct hlist_head bsg_device_list[BSG_LIST_ARRAY_SIZE];
3d6392cfb   Jens Axboe   bsg: support for ...
50
51
  
  static struct class *bsg_class;
46f6ef4af   Jens Axboe   bsg: convert to d...
52
  static int bsg_major;
3d6392cfb   Jens Axboe   bsg: support for ...
53

1c1133e1f   FUJITA Tomonori   bsg: device hash ...
54
  static inline struct hlist_head *bsg_dev_idx_hash(int index)
3d6392cfb   Jens Axboe   bsg: support for ...
55
  {
1c1133e1f   FUJITA Tomonori   bsg: device hash ...
56
  	return &bsg_device_list[index & (BSG_LIST_ARRAY_SIZE - 1)];
3d6392cfb   Jens Axboe   bsg: support for ...
57
  }
17cb960f2   Christoph Hellwig   bsg: split handli...
58
59
60
61
62
63
64
65
66
67
68
69
  #define uptr64(val) ((void __user *)(uintptr_t)(val))
  
  static int bsg_scsi_check_proto(struct sg_io_v4 *hdr)
  {
  	if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
  	    hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD)
  		return -EINVAL;
  	return 0;
  }
  
  static int bsg_scsi_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
  		fmode_t mode)
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
70
  {
17cb960f2   Christoph Hellwig   bsg: split handli...
71
  	struct scsi_request *sreq = scsi_req(rq);
82ed4db49   Christoph Hellwig   block: split scsi...
72

17cb960f2   Christoph Hellwig   bsg: split handli...
73
74
75
76
  	sreq->cmd_len = hdr->request_len;
  	if (sreq->cmd_len > BLK_MAX_CDB) {
  		sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL);
  		if (!sreq->cmd)
9f5de6b10   FUJITA Tomonori   [SCSI] bsg: add l...
77
78
  			return -ENOMEM;
  	}
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
79

17cb960f2   Christoph Hellwig   bsg: split handli...
80
  	if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len))
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
81
  		return -EFAULT;
17cb960f2   Christoph Hellwig   bsg: split handli...
82
  	if (blk_verify_command(sreq->cmd, mode))
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
83
  		return -EPERM;
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
84
85
  	return 0;
  }
17cb960f2   Christoph Hellwig   bsg: split handli...
86
  static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
3d6392cfb   Jens Axboe   bsg: support for ...
87
  {
17cb960f2   Christoph Hellwig   bsg: split handli...
88
  	struct scsi_request *sreq = scsi_req(rq);
15d10b611   FUJITA Tomonori   bsg: add SCSI tra...
89
  	int ret = 0;
17cb960f2   Christoph Hellwig   bsg: split handli...
90
91
92
93
94
95
96
97
98
99
  	/*
  	 * fill in all the output members
  	 */
  	hdr->device_status = sreq->result & 0xff;
  	hdr->transport_status = host_byte(sreq->result);
  	hdr->driver_status = driver_byte(sreq->result);
  	hdr->info = 0;
  	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
  		hdr->info |= SG_INFO_CHECK;
  	hdr->response_len = 0;
3d6392cfb   Jens Axboe   bsg: support for ...
100

17cb960f2   Christoph Hellwig   bsg: split handli...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  	if (sreq->sense_len && hdr->response) {
  		int len = min_t(unsigned int, hdr->max_response_len,
  					sreq->sense_len);
  
  		if (copy_to_user(uptr64(hdr->response), sreq->sense, len))
  			ret = -EFAULT;
  		else
  			hdr->response_len = len;
  	}
  
  	if (rq->next_rq) {
  		hdr->dout_resid = sreq->resid_len;
  		hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
  	} else if (rq_data_dir(rq) == READ) {
  		hdr->din_resid = sreq->resid_len;
  	} else {
  		hdr->dout_resid = sreq->resid_len;
15d10b611   FUJITA Tomonori   bsg: add SCSI tra...
118
  	}
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
119

15d10b611   FUJITA Tomonori   bsg: add SCSI tra...
120
  	return ret;
3d6392cfb   Jens Axboe   bsg: support for ...
121
  }
17cb960f2   Christoph Hellwig   bsg: split handli...
122
123
124
125
126
127
128
129
130
131
132
  static void bsg_scsi_free_rq(struct request *rq)
  {
  	scsi_req_free_cmd(scsi_req(rq));
  }
  
  static const struct bsg_ops bsg_scsi_ops = {
  	.check_proto		= bsg_scsi_check_proto,
  	.fill_hdr		= bsg_scsi_fill_hdr,
  	.complete_rq		= bsg_scsi_complete_rq,
  	.free_rq		= bsg_scsi_free_rq,
  };
3d6392cfb   Jens Axboe   bsg: support for ...
133
  static struct request *
17cb960f2   Christoph Hellwig   bsg: split handli...
134
  bsg_map_hdr(struct request_queue *q, struct sg_io_v4 *hdr, fmode_t mode)
3d6392cfb   Jens Axboe   bsg: support for ...
135
  {
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
136
  	struct request *rq, *next_rq = NULL;
aebf526b5   Christoph Hellwig   block: fold cmd_t...
137
  	int ret;
c7a841f3a   James Smart   [SCSI] bsg: corre...
138

17cb960f2   Christoph Hellwig   bsg: split handli...
139
  	if (!q->bsg_dev.class_dev)
c7a841f3a   James Smart   [SCSI] bsg: corre...
140
  		return ERR_PTR(-ENXIO);
3d6392cfb   Jens Axboe   bsg: support for ...
141

17cb960f2   Christoph Hellwig   bsg: split handli...
142
143
  	if (hdr->guard != 'Q')
  		return ERR_PTR(-EINVAL);
3d6392cfb   Jens Axboe   bsg: support for ...
144

17cb960f2   Christoph Hellwig   bsg: split handli...
145
  	ret = q->bsg_dev.ops->check_proto(hdr);
3d6392cfb   Jens Axboe   bsg: support for ...
146
147
  	if (ret)
  		return ERR_PTR(ret);
17cb960f2   Christoph Hellwig   bsg: split handli...
148
  	rq = blk_get_request(q, hdr->dout_xfer_len ?
ff005a066   Christoph Hellwig   block: sanitize b...
149
  			REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
a492f0754   Joe Lawrence   block,scsi: fixup...
150
151
  	if (IS_ERR(rq))
  		return rq;
f27b087b8   Jens Axboe   block: add blk_rq...
152

17cb960f2   Christoph Hellwig   bsg: split handli...
153
  	ret = q->bsg_dev.ops->fill_hdr(rq, hdr, mode);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
154
155
  	if (ret)
  		goto out;
17cb960f2   Christoph Hellwig   bsg: split handli...
156
157
158
159
160
161
162
163
164
  	rq->timeout = msecs_to_jiffies(hdr->timeout);
  	if (!rq->timeout)
  		rq->timeout = q->sg_timeout;
  	if (!rq->timeout)
  		rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
  	if (rq->timeout < BLK_MIN_SG_TIMEOUT)
  		rq->timeout = BLK_MIN_SG_TIMEOUT;
  
  	if (hdr->dout_xfer_len && hdr->din_xfer_len) {
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
165
166
167
168
  		if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) {
  			ret = -EOPNOTSUPP;
  			goto out;
  		}
ff005a066   Christoph Hellwig   block: sanitize b...
169
  		next_rq = blk_get_request(q, REQ_OP_SCSI_IN, 0);
a492f0754   Joe Lawrence   block,scsi: fixup...
170
171
  		if (IS_ERR(next_rq)) {
  			ret = PTR_ERR(next_rq);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
172
173
  			goto out;
  		}
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
174

17cb960f2   Christoph Hellwig   bsg: split handli...
175
176
  		rq->next_rq = next_rq;
  		ret = blk_rq_map_user(q, next_rq, NULL, uptr64(hdr->din_xferp),
152e283fd   FUJITA Tomonori   block: introduce ...
177
  				       hdr->din_xfer_len, GFP_KERNEL);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
178
  		if (ret)
17cb960f2   Christoph Hellwig   bsg: split handli...
179
  			goto out_free_nextrq;
3d6392cfb   Jens Axboe   bsg: support for ...
180
  	}
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
181
  	if (hdr->dout_xfer_len) {
17cb960f2   Christoph Hellwig   bsg: split handli...
182
183
  		ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->dout_xferp),
  				hdr->dout_xfer_len, GFP_KERNEL);
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
184
  	} else if (hdr->din_xfer_len) {
17cb960f2   Christoph Hellwig   bsg: split handli...
185
186
  		ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr->din_xferp),
  				hdr->din_xfer_len, GFP_KERNEL);
3d6392cfb   Jens Axboe   bsg: support for ...
187
  	}
c1c201200   Boaz Harrosh   bsg: Fix sense bu...
188

17cb960f2   Christoph Hellwig   bsg: split handli...
189
190
  	if (ret)
  		goto out_unmap_nextrq;
3d6392cfb   Jens Axboe   bsg: support for ...
191
  	return rq;
17cb960f2   Christoph Hellwig   bsg: split handli...
192
193
194
195
196
197
198
  
  out_unmap_nextrq:
  	if (rq->next_rq)
  		blk_rq_unmap_user(rq->next_rq->bio);
  out_free_nextrq:
  	if (rq->next_rq)
  		blk_put_request(rq->next_rq);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
199
  out:
17cb960f2   Christoph Hellwig   bsg: split handli...
200
  	q->bsg_dev.ops->free_rq(rq);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
201
  	blk_put_request(rq);
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
202
  	return ERR_PTR(ret);
3d6392cfb   Jens Axboe   bsg: support for ...
203
  }
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
204
  static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
205
  				    struct bio *bio, struct bio *bidi_bio)
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
206
  {
17cb960f2   Christoph Hellwig   bsg: split handli...
207
  	int ret;
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
208

17cb960f2   Christoph Hellwig   bsg: split handli...
209
  	ret = rq->q->bsg_dev.ops->complete_rq(rq, hdr);
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
210

2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
211
212
213
  	if (rq->next_rq) {
  		blk_rq_unmap_user(bidi_bio);
  		blk_put_request(rq->next_rq);
17cb960f2   Christoph Hellwig   bsg: split handli...
214
  	}
2d507a01d   James Bottomley   [SCSI] libsas, bs...
215

70e36ecea   FUJITA Tomonori   bsg: replace SG v...
216
  	blk_rq_unmap_user(bio);
17cb960f2   Christoph Hellwig   bsg: split handli...
217
  	rq->q->bsg_dev.ops->free_rq(rq);
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
218
  	blk_put_request(rq);
70e36ecea   FUJITA Tomonori   bsg: replace SG v...
219
220
  	return ret;
  }
3d6392cfb   Jens Axboe   bsg: support for ...
221
222
  static struct bsg_device *bsg_alloc_device(void)
  {
3d6392cfb   Jens Axboe   bsg: support for ...
223
  	struct bsg_device *bd;
3d6392cfb   Jens Axboe   bsg: support for ...
224
225
226
227
228
229
  
  	bd = kzalloc(sizeof(struct bsg_device), GFP_KERNEL);
  	if (unlikely(!bd))
  		return NULL;
  
  	spin_lock_init(&bd->lock);
5309cb38d   Jens Axboe   Add queue resizin...
230
  	bd->max_queue = BSG_DEFAULT_CMDS;
3d6392cfb   Jens Axboe   bsg: support for ...
231
  	INIT_HLIST_NODE(&bd->dev_list);
3d6392cfb   Jens Axboe   bsg: support for ...
232
  	return bd;
3d6392cfb   Jens Axboe   bsg: support for ...
233
234
235
236
  }
  
  static int bsg_put_device(struct bsg_device *bd)
  {
97f46ae45   FUJITA Tomonori   [SCSI] bsg: add r...
237
  	struct request_queue *q = bd->queue;
3d6392cfb   Jens Axboe   bsg: support for ...
238
239
  
  	mutex_lock(&bsg_mutex);
db193954e   John Pittman   block: bsg: move ...
240
  	if (!refcount_dec_and_test(&bd->ref_count)) {
3f27e3ed1   FUJITA Tomonori   [SCSI] bsg: fix b...
241
  		mutex_unlock(&bsg_mutex);
28519c891   Christoph Hellwig   bsg: remove read/...
242
  		return 0;
3f27e3ed1   FUJITA Tomonori   [SCSI] bsg: fix b...
243
244
245
246
  	}
  
  	hlist_del(&bd->dev_list);
  	mutex_unlock(&bsg_mutex);
3d6392cfb   Jens Axboe   bsg: support for ...
247

3124b65da   Johannes Thumshirn   bsg: use pr_debug...
248
249
  	bsg_dbg(bd, "tearing down
  ");
3d6392cfb   Jens Axboe   bsg: support for ...
250
251
252
253
  
  	/*
  	 * close can always block
  	 */
5309cb38d   Jens Axboe   Add queue resizin...
254
  	kfree(bd);
28519c891   Christoph Hellwig   bsg: remove read/...
255
256
  	blk_put_queue(q);
  	return 0;
3d6392cfb   Jens Axboe   bsg: support for ...
257
258
259
  }
  
  static struct bsg_device *bsg_add_device(struct inode *inode,
d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
260
  					 struct request_queue *rq,
3d6392cfb   Jens Axboe   bsg: support for ...
261
262
  					 struct file *file)
  {
25fd16430   Jens Axboe   bsg: address vari...
263
  	struct bsg_device *bd;
3d6392cfb   Jens Axboe   bsg: support for ...
264
  	unsigned char buf[32];
d9f972644   Bart Van Assche   bsg: Check queue ...
265

d6c73964f   Anatoliy Glagolev   bsg: fix race of ...
266
  	lockdep_assert_held(&bsg_mutex);
09ac46c42   Tejun Heo   block: misc updat...
267
  	if (!blk_get_queue(rq))
c3ff1b90d   FUJITA Tomonori   [SCSI] bsg: repla...
268
  		return ERR_PTR(-ENXIO);
3d6392cfb   Jens Axboe   bsg: support for ...
269
270
  
  	bd = bsg_alloc_device();
c3ff1b90d   FUJITA Tomonori   [SCSI] bsg: repla...
271
272
  	if (!bd) {
  		blk_put_queue(rq);
3d6392cfb   Jens Axboe   bsg: support for ...
273
  		return ERR_PTR(-ENOMEM);
c3ff1b90d   FUJITA Tomonori   [SCSI] bsg: repla...
274
  	}
3d6392cfb   Jens Axboe   bsg: support for ...
275

d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
276
  	bd->queue = rq;
0b07de85a   Adel Gadllah   allow userspace t...
277

db193954e   John Pittman   block: bsg: move ...
278
  	refcount_set(&bd->ref_count, 1);
842ea771c   FUJITA Tomonori   [SCSI] bsg: remov...
279
  	hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
3d6392cfb   Jens Axboe   bsg: support for ...
280

3ada8b7e9   Kay Sievers   block: struct dev...
281
  	strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
3124b65da   Johannes Thumshirn   bsg: use pr_debug...
282
283
  	bsg_dbg(bd, "bound to <%s>, max queue %d
  ",
9e69fbb53   FUJITA Tomonori   bsg: minor cleanups
284
  		format_dev_t(buf, inode->i_rdev), bd->max_queue);
3d6392cfb   Jens Axboe   bsg: support for ...
285

3d6392cfb   Jens Axboe   bsg: support for ...
286
287
  	return bd;
  }
842ea771c   FUJITA Tomonori   [SCSI] bsg: remov...
288
  static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
3d6392cfb   Jens Axboe   bsg: support for ...
289
  {
43ac9e62c   FUJITA Tomonori   [SCSI] bsg: use b...
290
  	struct bsg_device *bd;
3d6392cfb   Jens Axboe   bsg: support for ...
291

d6c73964f   Anatoliy Glagolev   bsg: fix race of ...
292
  	lockdep_assert_held(&bsg_mutex);
3d6392cfb   Jens Axboe   bsg: support for ...
293

b67bfe0d4   Sasha Levin   hlist: drop the n...
294
  	hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
842ea771c   FUJITA Tomonori   [SCSI] bsg: remov...
295
  		if (bd->queue == q) {
db193954e   John Pittman   block: bsg: move ...
296
  			refcount_inc(&bd->ref_count);
43ac9e62c   FUJITA Tomonori   [SCSI] bsg: use b...
297
  			goto found;
3d6392cfb   Jens Axboe   bsg: support for ...
298
  		}
3d6392cfb   Jens Axboe   bsg: support for ...
299
  	}
43ac9e62c   FUJITA Tomonori   [SCSI] bsg: use b...
300
301
  	bd = NULL;
  found:
3d6392cfb   Jens Axboe   bsg: support for ...
302
303
304
305
306
  	return bd;
  }
  
  static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
  {
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
307
308
  	struct bsg_device *bd;
  	struct bsg_class_device *bcd;
3d6392cfb   Jens Axboe   bsg: support for ...
309

3d6392cfb   Jens Axboe   bsg: support for ...
310
311
312
  	/*
  	 * find the class device
  	 */
3d6392cfb   Jens Axboe   bsg: support for ...
313
  	mutex_lock(&bsg_mutex);
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
314
  	bcd = idr_find(&bsg_minor_idr, iminor(inode));
3d6392cfb   Jens Axboe   bsg: support for ...
315

d6c73964f   Anatoliy Glagolev   bsg: fix race of ...
316
317
318
319
  	if (!bcd) {
  		bd = ERR_PTR(-ENODEV);
  		goto out_unlock;
  	}
3d6392cfb   Jens Axboe   bsg: support for ...
320

842ea771c   FUJITA Tomonori   [SCSI] bsg: remov...
321
  	bd = __bsg_get_device(iminor(inode), bcd->queue);
d6c73964f   Anatoliy Glagolev   bsg: fix race of ...
322
323
  	if (!bd)
  		bd = bsg_add_device(inode, bcd->queue, file);
d45ac4fa8   FUJITA Tomonori   [SCSI] bsg: takes...
324

d6c73964f   Anatoliy Glagolev   bsg: fix race of ...
325
326
  out_unlock:
  	mutex_unlock(&bsg_mutex);
d45ac4fa8   FUJITA Tomonori   [SCSI] bsg: takes...
327
  	return bd;
3d6392cfb   Jens Axboe   bsg: support for ...
328
329
330
331
  }
  
  static int bsg_open(struct inode *inode, struct file *file)
  {
75bd2ef14   Jonathan Corbet   bsg: cdev lock_ke...
332
  	struct bsg_device *bd;
75bd2ef14   Jonathan Corbet   bsg: cdev lock_ke...
333
  	bd = bsg_get_device(inode, file);
3d6392cfb   Jens Axboe   bsg: support for ...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  
  	if (IS_ERR(bd))
  		return PTR_ERR(bd);
  
  	file->private_data = bd;
  	return 0;
  }
  
  static int bsg_release(struct inode *inode, struct file *file)
  {
  	struct bsg_device *bd = file->private_data;
  
  	file->private_data = NULL;
  	return bsg_put_device(bd);
  }
25fd16430   Jens Axboe   bsg: address vari...
349
  static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3d6392cfb   Jens Axboe   bsg: support for ...
350
351
352
  {
  	struct bsg_device *bd = file->private_data;
  	int __user *uarg = (int __user *) arg;
2d507a01d   James Bottomley   [SCSI] libsas, bs...
353
  	int ret;
3d6392cfb   Jens Axboe   bsg: support for ...
354

3d6392cfb   Jens Axboe   bsg: support for ...
355
356
357
358
359
360
  	switch (cmd) {
  		/*
  		 * our own ioctls
  		 */
  	case SG_GET_COMMAND_Q:
  		return put_user(bd->max_queue, uarg);
5309cb38d   Jens Axboe   Add queue resizin...
361
  	case SG_SET_COMMAND_Q: {
3d6392cfb   Jens Axboe   bsg: support for ...
362
363
364
365
  		int queue;
  
  		if (get_user(queue, uarg))
  			return -EFAULT;
5309cb38d   Jens Axboe   Add queue resizin...
366
  		if (queue < 1)
3d6392cfb   Jens Axboe   bsg: support for ...
367
  			return -EINVAL;
5309cb38d   Jens Axboe   Add queue resizin...
368
  		spin_lock_irq(&bd->lock);
3d6392cfb   Jens Axboe   bsg: support for ...
369
  		bd->max_queue = queue;
5309cb38d   Jens Axboe   Add queue resizin...
370
  		spin_unlock_irq(&bd->lock);
3d6392cfb   Jens Axboe   bsg: support for ...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  		return 0;
  	}
  
  	/*
  	 * SCSI/sg ioctls
  	 */
  	case SG_GET_VERSION_NUM:
  	case SCSI_IOCTL_GET_IDLUN:
  	case SCSI_IOCTL_GET_BUS_NUMBER:
  	case SG_SET_TIMEOUT:
  	case SG_GET_TIMEOUT:
  	case SG_GET_RESERVED_SIZE:
  	case SG_SET_RESERVED_SIZE:
  	case SG_EMULATED_HOST:
3d6392cfb   Jens Axboe   bsg: support for ...
385
386
  	case SCSI_IOCTL_SEND_COMMAND: {
  		void __user *uarg = (void __user *) arg;
74f3c8aff   Al Viro   [PATCH] switch sc...
387
  		return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg);
3d6392cfb   Jens Axboe   bsg: support for ...
388
  	}
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
389
390
  	case SG_IO: {
  		struct request *rq;
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
391
  		struct bio *bio, *bidi_bio = NULL;
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
392
  		struct sg_io_v4 hdr;
05378940c   Boaz Harrosh   bsg: add support ...
393
  		int at_head;
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
394
395
396
  
  		if (copy_from_user(&hdr, uarg, sizeof(hdr)))
  			return -EFAULT;
17cb960f2   Christoph Hellwig   bsg: split handli...
397
  		rq = bsg_map_hdr(bd->queue, &hdr, file->f_mode);
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
398
399
400
401
  		if (IS_ERR(rq))
  			return PTR_ERR(rq);
  
  		bio = rq->bio;
2c9ecdf40   FUJITA Tomonori   bsg: add bidi sup...
402
403
  		if (rq->next_rq)
  			bidi_bio = rq->next_rq->bio;
05378940c   Boaz Harrosh   bsg: add support ...
404
405
406
  
  		at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL));
  		blk_execute_rq(bd->queue, NULL, rq, at_head);
2d507a01d   James Bottomley   [SCSI] libsas, bs...
407
  		ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
408
409
410
  
  		if (copy_to_user(uarg, &hdr, sizeof(hdr)))
  			return -EFAULT;
b711afa69   Jens Axboe   bsg: style cleanup
411

2d507a01d   James Bottomley   [SCSI] libsas, bs...
412
  		return ret;
10e8855b9   FUJITA Tomonori   bsg: add SG_IO to...
413
  	}
3d6392cfb   Jens Axboe   bsg: support for ...
414
  	default:
3d6392cfb   Jens Axboe   bsg: support for ...
415
  		return -ENOTTY;
3d6392cfb   Jens Axboe   bsg: support for ...
416
417
  	}
  }
7344be053   Arjan van de Ven   bsg: mark struct ...
418
  static const struct file_operations bsg_fops = {
3d6392cfb   Jens Axboe   bsg: support for ...
419
420
  	.open		=	bsg_open,
  	.release	=	bsg_release,
25fd16430   Jens Axboe   bsg: address vari...
421
  	.unlocked_ioctl	=	bsg_ioctl,
3d6392cfb   Jens Axboe   bsg: support for ...
422
  	.owner		=	THIS_MODULE,
6038f373a   Arnd Bergmann   llseek: automatic...
423
  	.llseek		=	default_llseek,
3d6392cfb   Jens Axboe   bsg: support for ...
424
  };
d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
425
  void bsg_unregister_queue(struct request_queue *q)
3d6392cfb   Jens Axboe   bsg: support for ...
426
  {
d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
427
  	struct bsg_class_device *bcd = &q->bsg_dev;
3d6392cfb   Jens Axboe   bsg: support for ...
428

df468820b   FUJITA Tomonori   [SCSI] bsg: fix b...
429
430
  	if (!bcd->class_dev)
  		return;
3d6392cfb   Jens Axboe   bsg: support for ...
431
432
  
  	mutex_lock(&bsg_mutex);
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
433
  	idr_remove(&bsg_minor_idr, bcd->minor);
37b40adf2   Stanislaw Gruszka   bsg: fix sysfs li...
434
435
  	if (q->kobj.sd)
  		sysfs_remove_link(&q->kobj, "bsg");
ee959b00c   Tony Jones   SCSI: convert str...
436
  	device_unregister(bcd->class_dev);
3d6392cfb   Jens Axboe   bsg: support for ...
437
  	bcd->class_dev = NULL;
3d6392cfb   Jens Axboe   bsg: support for ...
438
439
  	mutex_unlock(&bsg_mutex);
  }
4cf0723ac   FUJITA Tomonori   bsg: minor bug fixes
440
  EXPORT_SYMBOL_GPL(bsg_unregister_queue);
3d6392cfb   Jens Axboe   bsg: support for ...
441

97f46ae45   FUJITA Tomonori   [SCSI] bsg: add r...
442
  int bsg_register_queue(struct request_queue *q, struct device *parent,
5de815a7e   Christoph Hellwig   block: remove par...
443
  		const char *name, const struct bsg_ops *ops)
3d6392cfb   Jens Axboe   bsg: support for ...
444
  {
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
445
  	struct bsg_class_device *bcd;
3d6392cfb   Jens Axboe   bsg: support for ...
446
  	dev_t dev;
bab998d62   Tejun Heo   block: convert to...
447
  	int ret;
ee959b00c   Tony Jones   SCSI: convert str...
448
  	struct device *class_dev = NULL;
3d6392cfb   Jens Axboe   bsg: support for ...
449
450
451
452
  
  	/*
  	 * we need a proper transport to send commands, not a stacked device
  	 */
49fd524f9   Jens Axboe   bsg: update check...
453
  	if (!queue_is_rq_based(q))
3d6392cfb   Jens Axboe   bsg: support for ...
454
  		return 0;
d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
455
  	bcd = &q->bsg_dev;
3d6392cfb   Jens Axboe   bsg: support for ...
456
  	memset(bcd, 0, sizeof(*bcd));
3d6392cfb   Jens Axboe   bsg: support for ...
457
458
  
  	mutex_lock(&bsg_mutex);
292b7f271   FUJITA Tomonori   improve bsg devic...
459

bab998d62   Tejun Heo   block: convert to...
460
461
462
463
464
465
466
  	ret = idr_alloc(&bsg_minor_idr, bcd, 0, BSG_MAX_DEVS, GFP_KERNEL);
  	if (ret < 0) {
  		if (ret == -ENOSPC) {
  			printk(KERN_ERR "bsg: too many bsg devices
  ");
  			ret = -EINVAL;
  		}
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
467
  		goto unlock;
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
468
  	}
bab998d62   Tejun Heo   block: convert to...
469
  	bcd->minor = ret;
d351af01b   FUJITA Tomonori   bsg: bind bsg to ...
470
  	bcd->queue = q;
17cb960f2   Christoph Hellwig   bsg: split handli...
471
  	bcd->ops = ops;
46f6ef4af   Jens Axboe   bsg: convert to d...
472
  	dev = MKDEV(bsg_major, bcd->minor);
5de815a7e   Christoph Hellwig   block: remove par...
473
  	class_dev = device_create(bsg_class, parent, dev, NULL, "%s", name);
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
474
475
  	if (IS_ERR(class_dev)) {
  		ret = PTR_ERR(class_dev);
5de815a7e   Christoph Hellwig   block: remove par...
476
  		goto idr_remove;
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
477
478
  	}
  	bcd->class_dev = class_dev;
abce891a1   Linus Torvalds   Fix new generic b...
479
  	if (q->kobj.sd) {
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
480
481
  		ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
  		if (ret)
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
482
  			goto unregister_class_dev;
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
483
  	}
3d6392cfb   Jens Axboe   bsg: support for ...
484
485
  	mutex_unlock(&bsg_mutex);
  	return 0;
6826ee4fd   James Bottomley   [SCSI] bsg: fix b...
486

598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
487
  unregister_class_dev:
ee959b00c   Tony Jones   SCSI: convert str...
488
  	device_unregister(class_dev);
5de815a7e   Christoph Hellwig   block: remove par...
489
  idr_remove:
bab998d62   Tejun Heo   block: convert to...
490
  	idr_remove(&bsg_minor_idr, bcd->minor);
598443a21   FUJITA Tomonori   [SCSI] bsg: use l...
491
  unlock:
264a04721   Jens Axboe   bsg: add cheasy e...
492
  	mutex_unlock(&bsg_mutex);
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
493
494
  	return ret;
  }
17cb960f2   Christoph Hellwig   bsg: split handli...
495
496
497
498
499
500
501
502
  
  int bsg_scsi_register_queue(struct request_queue *q, struct device *parent)
  {
  	if (!blk_queue_scsi_passthrough(q)) {
  		WARN_ONCE(true, "Attempt to register a non-SCSI queue
  ");
  		return -EINVAL;
  	}
5de815a7e   Christoph Hellwig   block: remove par...
503
  	return bsg_register_queue(q, parent, dev_name(parent), &bsg_scsi_ops);
17cb960f2   Christoph Hellwig   bsg: split handli...
504
505
  }
  EXPORT_SYMBOL_GPL(bsg_scsi_register_queue);
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
506

7e7654a92   Greg Kroah-Hartman   cdev: remove unne...
507
  static struct cdev bsg_cdev;
292b7f271   FUJITA Tomonori   improve bsg devic...
508

2c9ede55e   Al Viro   switch device_get...
509
  static char *bsg_devnode(struct device *dev, umode_t *mode)
2bdf91491   Kay Sievers   Driver Core: bsg:...
510
511
512
  {
  	return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev));
  }
3d6392cfb   Jens Axboe   bsg: support for ...
513
514
515
  static int __init bsg_init(void)
  {
  	int ret, i;
46f6ef4af   Jens Axboe   bsg: convert to d...
516
  	dev_t devid;
3d6392cfb   Jens Axboe   bsg: support for ...
517

25fd16430   Jens Axboe   bsg: address vari...
518
  	for (i = 0; i < BSG_LIST_ARRAY_SIZE; i++)
3d6392cfb   Jens Axboe   bsg: support for ...
519
520
521
  		INIT_HLIST_HEAD(&bsg_device_list[i]);
  
  	bsg_class = class_create(THIS_MODULE, "bsg");
28519c891   Christoph Hellwig   bsg: remove read/...
522
523
  	if (IS_ERR(bsg_class))
  		return PTR_ERR(bsg_class);
e454cea20   Kay Sievers   Driver-Core: exte...
524
  	bsg_class->devnode = bsg_devnode;
3d6392cfb   Jens Axboe   bsg: support for ...
525

46f6ef4af   Jens Axboe   bsg: convert to d...
526
  	ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg");
9b9f770ce   FUJITA Tomonori   bsg: fix initiali...
527
528
  	if (ret)
  		goto destroy_bsg_class;
292b7f271   FUJITA Tomonori   improve bsg devic...
529

46f6ef4af   Jens Axboe   bsg: convert to d...
530
  	bsg_major = MAJOR(devid);
292b7f271   FUJITA Tomonori   improve bsg devic...
531
  	cdev_init(&bsg_cdev, &bsg_fops);
46f6ef4af   Jens Axboe   bsg: convert to d...
532
  	ret = cdev_add(&bsg_cdev, MKDEV(bsg_major, 0), BSG_MAX_DEVS);
9b9f770ce   FUJITA Tomonori   bsg: fix initiali...
533
534
  	if (ret)
  		goto unregister_chrdev;
3d6392cfb   Jens Axboe   bsg: support for ...
535

5d3a8cd34   Jens Axboe   bsg: fix missing ...
536
  	printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION
0ed081ce2   FUJITA Tomonori   bsg: minor cleanup
537
538
  	       " loaded (major %d)
  ", bsg_major);
3d6392cfb   Jens Axboe   bsg: support for ...
539
  	return 0;
9b9f770ce   FUJITA Tomonori   bsg: fix initiali...
540
541
542
543
  unregister_chrdev:
  	unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS);
  destroy_bsg_class:
  	class_destroy(bsg_class);
9b9f770ce   FUJITA Tomonori   bsg: fix initiali...
544
  	return ret;
3d6392cfb   Jens Axboe   bsg: support for ...
545
546
547
  }
  
  MODULE_AUTHOR("Jens Axboe");
0ed081ce2   FUJITA Tomonori   bsg: minor cleanup
548
  MODULE_DESCRIPTION(BSG_DESCRIPTION);
3d6392cfb   Jens Axboe   bsg: support for ...
549
  MODULE_LICENSE("GPL");
4e2872d6b   FUJITA Tomonori   bind bsg to all S...
550
  device_initcall(bsg_init);