diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/ll_rw_blk.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index f20eba22b14b..e30a3c93b70c 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
@@ -281,6 +281,7 @@ static inline void rq_init(request_queue_t *q, struct request *rq) | |||
281 | rq->special = NULL; | 281 | rq->special = NULL; |
282 | rq->data_len = 0; | 282 | rq->data_len = 0; |
283 | rq->data = NULL; | 283 | rq->data = NULL; |
284 | rq->nr_phys_segments = 0; | ||
284 | rq->sense = NULL; | 285 | rq->sense = NULL; |
285 | rq->end_io = NULL; | 286 | rq->end_io = NULL; |
286 | rq->end_io_data = NULL; | 287 | rq->end_io_data = NULL; |
@@ -2176,6 +2177,61 @@ int blk_rq_unmap_user(struct request *rq, struct bio *bio, unsigned int ulen) | |||
2176 | 2177 | ||
2177 | EXPORT_SYMBOL(blk_rq_unmap_user); | 2178 | EXPORT_SYMBOL(blk_rq_unmap_user); |
2178 | 2179 | ||
2180 | static int blk_rq_map_kern_endio(struct bio *bio, unsigned int bytes_done, | ||
2181 | int error) | ||
2182 | { | ||
2183 | if (bio->bi_size) | ||
2184 | return 1; | ||
2185 | |||
2186 | bio_put(bio); | ||
2187 | return 0; | ||
2188 | } | ||
2189 | |||
2190 | /** | ||
2191 | * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage | ||
2192 | * @q: request queue where request should be inserted | ||
2193 | * @rw: READ or WRITE data | ||
2194 | * @kbuf: the kernel buffer | ||
2195 | * @len: length of user data | ||
2196 | */ | ||
2197 | struct request *blk_rq_map_kern(request_queue_t *q, int rw, void *kbuf, | ||
2198 | unsigned int len, unsigned int gfp_mask) | ||
2199 | { | ||
2200 | struct request *rq; | ||
2201 | struct bio *bio; | ||
2202 | |||
2203 | if (len > (q->max_sectors << 9)) | ||
2204 | return ERR_PTR(-EINVAL); | ||
2205 | if ((!len && kbuf) || (len && !kbuf)) | ||
2206 | return ERR_PTR(-EINVAL); | ||
2207 | |||
2208 | rq = blk_get_request(q, rw, gfp_mask); | ||
2209 | if (!rq) | ||
2210 | return ERR_PTR(-ENOMEM); | ||
2211 | |||
2212 | bio = bio_map_kern(q, kbuf, len, gfp_mask); | ||
2213 | if (!IS_ERR(bio)) { | ||
2214 | if (rw) | ||
2215 | bio->bi_rw |= (1 << BIO_RW); | ||
2216 | bio->bi_end_io = blk_rq_map_kern_endio; | ||
2217 | |||
2218 | rq->bio = rq->biotail = bio; | ||
2219 | blk_rq_bio_prep(q, rq, bio); | ||
2220 | |||
2221 | rq->buffer = rq->data = NULL; | ||
2222 | rq->data_len = len; | ||
2223 | return rq; | ||
2224 | } | ||
2225 | |||
2226 | /* | ||
2227 | * bio is the err-ptr | ||
2228 | */ | ||
2229 | blk_put_request(rq); | ||
2230 | return (struct request *) bio; | ||
2231 | } | ||
2232 | |||
2233 | EXPORT_SYMBOL(blk_rq_map_kern); | ||
2234 | |||
2179 | /** | 2235 | /** |
2180 | * blk_execute_rq - insert a request into queue for execution | 2236 | * blk_execute_rq - insert a request into queue for execution |
2181 | * @q: queue to insert the request in | 2237 | * @q: queue to insert the request in |