Lines Matching +full:io +full:- +full:backends

6  * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
40 #include <linux/blk-mq.h>
61 #include <xen/interface/io/blkif.h>
62 #include <xen/interface/io/protocols.h>
160 __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
163 * ring-ref%u i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
168 * queue-%u would take 7 + 10(UINT_MAX) = 17 characters.
173 * Per-ring info.
196 * putting all kinds of interesting stuff here :-)
216 /* Connect-time cached feature_persistent parameter */
275 for ((ptr) = (info)->rinfo, (idx) = 0; \
276 (idx) < (info)->nr_rings; \
277 (idx)++, (ptr) = (void *)(ptr) + (info)->rinfo_size)
282 BUG_ON(i >= info->nr_rings); in get_rinfo()
283 return (void *)info->rinfo + i * info->rinfo_size; in get_rinfo()
288 unsigned long free = rinfo->shadow_free; in get_id_from_freelist()
290 BUG_ON(free >= BLK_RING_SIZE(rinfo->dev_info)); in get_id_from_freelist()
291 rinfo->shadow_free = rinfo->shadow[free].req.u.rw.id; in get_id_from_freelist()
292 rinfo->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */ in get_id_from_freelist()
299 if (rinfo->shadow[id].req.u.rw.id != id) in add_id_to_freelist()
300 return -EINVAL; in add_id_to_freelist()
301 if (rinfo->shadow[id].request == NULL) in add_id_to_freelist()
302 return -EINVAL; in add_id_to_freelist()
303 rinfo->shadow[id].req.u.rw.id = rinfo->shadow_free; in add_id_to_freelist()
304 rinfo->shadow[id].request = NULL; in add_id_to_freelist()
305 rinfo->shadow_free = id; in add_id_to_freelist()
311 struct blkfront_info *info = rinfo->dev_info; in fill_grant_buffer()
321 if (info->bounce) { in fill_grant_buffer()
327 gnt_list_entry->page = granted_page; in fill_grant_buffer()
330 gnt_list_entry->gref = INVALID_GRANT_REF; in fill_grant_buffer()
331 list_add(&gnt_list_entry->node, &rinfo->grants); in fill_grant_buffer()
339 &rinfo->grants, node) { in fill_grant_buffer()
340 list_del(&gnt_list_entry->node); in fill_grant_buffer()
341 if (info->bounce) in fill_grant_buffer()
342 __free_page(gnt_list_entry->page); in fill_grant_buffer()
344 i--; in fill_grant_buffer()
347 return -ENOMEM; in fill_grant_buffer()
354 BUG_ON(list_empty(&rinfo->grants)); in get_free_grant()
355 gnt_list_entry = list_first_entry(&rinfo->grants, struct grant, in get_free_grant()
357 list_del(&gnt_list_entry->node); in get_free_grant()
359 if (gnt_list_entry->gref != INVALID_GRANT_REF) in get_free_grant()
360 rinfo->persistent_gnts_c--; in get_free_grant()
368 gnttab_page_grant_foreign_access_ref_one(gnt_list_entry->gref, in grant_foreign_access()
369 info->xbdev->otherend_id, in grant_foreign_access()
370 gnt_list_entry->page, in grant_foreign_access()
379 struct blkfront_info *info = rinfo->dev_info; in get_grant()
381 if (gnt_list_entry->gref != INVALID_GRANT_REF) in get_grant()
385 gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); in get_grant()
386 BUG_ON(gnt_list_entry->gref == -ENOSPC); in get_grant()
387 if (info->bounce) in get_grant()
391 gnttab_grant_foreign_access_ref(gnt_list_entry->gref, in get_grant()
392 info->xbdev->otherend_id, in get_grant()
403 struct blkfront_info *info = rinfo->dev_info; in get_indirect_grant()
405 if (gnt_list_entry->gref != INVALID_GRANT_REF) in get_indirect_grant()
409 gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); in get_indirect_grant()
410 BUG_ON(gnt_list_entry->gref == -ENOSPC); in get_indirect_grant()
411 if (!info->bounce) { in get_indirect_grant()
414 /* Fetch a pre-allocated page to use for indirect grefs */ in get_indirect_grant()
415 BUG_ON(list_empty(&rinfo->indirect_pages)); in get_indirect_grant()
416 indirect_page = list_first_entry(&rinfo->indirect_pages, in get_indirect_grant()
418 list_del(&indirect_page->lru); in get_indirect_grant()
419 gnt_list_entry->page = indirect_page; in get_indirect_grant()
454 return -ENOMEM; in xlbd_reserve_minors()
474 rc = -EBUSY; in xlbd_reserve_minors()
493 schedule_work(&rinfo->work); in blkif_restart_queue_callback()
500 sector_t nsect = get_capacity(bd->bd_disk); in blkif_getgeo()
503 hg->heads = 0xff; in blkif_getgeo()
504 hg->sectors = 0x3f; in blkif_getgeo()
505 sector_div(cylinders, hg->heads * hg->sectors); in blkif_getgeo()
506 hg->cylinders = cylinders; in blkif_getgeo()
507 if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect) in blkif_getgeo()
508 hg->cylinders = 0xffff; in blkif_getgeo()
515 struct blkfront_info *info = bdev->bd_disk->private_data; in blkif_ioctl()
522 return -EFAULT; in blkif_ioctl()
525 if (!(info->vdisk_info & VDISK_CDROM)) in blkif_ioctl()
526 return -EINVAL; in blkif_ioctl()
529 return -EINVAL; in blkif_ioctl()
539 *ring_req = RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt); in blkif_ring_get_request()
540 rinfo->ring.req_prod_pvt++; in blkif_ring_get_request()
543 rinfo->shadow[id].request = req; in blkif_ring_get_request()
544 rinfo->shadow[id].status = REQ_PROCESSING; in blkif_ring_get_request()
545 rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID; in blkif_ring_get_request()
547 rinfo->shadow[id].req.u.rw.id = id; in blkif_ring_get_request()
554 struct blkfront_info *info = rinfo->dev_info; in blkif_queue_discard_req()
560 ring_req = &rinfo->shadow[id].req; in blkif_queue_discard_req()
562 ring_req->operation = BLKIF_OP_DISCARD; in blkif_queue_discard_req()
563 ring_req->u.discard.nr_sectors = blk_rq_sectors(req); in blkif_queue_discard_req()
564 ring_req->u.discard.id = id; in blkif_queue_discard_req()
565 ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req); in blkif_queue_discard_req()
566 if (req_op(req) == REQ_OP_SECURE_ERASE && info->feature_secdiscard) in blkif_queue_discard_req()
567 ring_req->u.discard.flag = BLKIF_DISCARD_SECURE; in blkif_queue_discard_req()
569 ring_req->u.discard.flag = 0; in blkif_queue_discard_req()
573 rinfo->shadow[id].status = REQ_WAITING; in blkif_queue_discard_req()
602 unsigned int grant_idx = setup->grant_idx; in blkif_setup_rw_req_grant()
603 struct blkif_request *ring_req = setup->ring_req; in blkif_setup_rw_req_grant()
604 struct blkfront_ring_info *rinfo = setup->rinfo; in blkif_setup_rw_req_grant()
611 struct blk_shadow *shadow = &rinfo->shadow[setup->id]; in blkif_setup_rw_req_grant()
613 if (unlikely(setup->require_extra_req && in blkif_setup_rw_req_grant()
619 grant_idx -= BLKIF_MAX_SEGMENTS_PER_REQUEST; in blkif_setup_rw_req_grant()
620 ring_req = setup->extra_ring_req; in blkif_setup_rw_req_grant()
623 if ((ring_req->operation == BLKIF_OP_INDIRECT) && in blkif_setup_rw_req_grant()
625 if (setup->segments) in blkif_setup_rw_req_grant()
626 kunmap_atomic(setup->segments); in blkif_setup_rw_req_grant()
629 gnt_list_entry = get_indirect_grant(&setup->gref_head, rinfo); in blkif_setup_rw_req_grant()
630 shadow->indirect_grants[n] = gnt_list_entry; in blkif_setup_rw_req_grant()
631 setup->segments = kmap_atomic(gnt_list_entry->page); in blkif_setup_rw_req_grant()
632 ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref; in blkif_setup_rw_req_grant()
635 gnt_list_entry = get_grant(&setup->gref_head, gfn, rinfo); in blkif_setup_rw_req_grant()
636 ref = gnt_list_entry->gref; in blkif_setup_rw_req_grant()
641 shadow->grants_used[setup->grant_idx] = gnt_list_entry; in blkif_setup_rw_req_grant()
643 if (setup->need_copy) { in blkif_setup_rw_req_grant()
646 shared_data = kmap_atomic(gnt_list_entry->page); in blkif_setup_rw_req_grant()
649 * range sg->offset..sg->offset+sg->length. in blkif_setup_rw_req_grant()
657 setup->bvec_data + setup->bvec_off, in blkif_setup_rw_req_grant()
661 setup->bvec_off += len; in blkif_setup_rw_req_grant()
665 lsect = fsect + (len >> 9) - 1; in blkif_setup_rw_req_grant()
666 if (ring_req->operation != BLKIF_OP_INDIRECT) { in blkif_setup_rw_req_grant()
667 ring_req->u.rw.seg[grant_idx] = in blkif_setup_rw_req_grant()
673 setup->segments[grant_idx % GRANTS_PER_INDIRECT_FRAME] = in blkif_setup_rw_req_grant()
680 (setup->grant_idx)++; in blkif_setup_rw_req_grant()
686 uint16_t nr_segments = first->u.rw.nr_segments; in blkif_setup_extra_req()
692 first->u.rw.nr_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST; in blkif_setup_extra_req()
694 second->u.rw.nr_segments = nr_segments - BLKIF_MAX_SEGMENTS_PER_REQUEST; in blkif_setup_extra_req()
695 second->u.rw.sector_number = first->u.rw.sector_number + in blkif_setup_extra_req()
698 second->u.rw.handle = first->u.rw.handle; in blkif_setup_extra_req()
699 second->operation = first->operation; in blkif_setup_extra_req()
704 struct blkfront_info *info = rinfo->dev_info; in blkif_queue_rw_req()
714 .need_copy = rq_data_dir(req) && info->bounce, in blkif_queue_rw_req()
726 max_grefs = req->nr_phys_segments * GRANTS_PER_PSEG; in blkif_queue_rw_req()
735 if (rinfo->persistent_gnts_c < max_grefs) { in blkif_queue_rw_req()
739 max_grefs - rinfo->persistent_gnts_c, in blkif_queue_rw_req()
742 &rinfo->callback, in blkif_queue_rw_req()
745 max_grefs - rinfo->persistent_gnts_c); in blkif_queue_rw_req()
752 ring_req = &rinfo->shadow[id].req; in blkif_queue_rw_req()
754 num_sg = blk_rq_map_sg(req, rinfo->shadow[id].sg); in blkif_queue_rw_req()
757 for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i) in blkif_queue_rw_req()
758 num_grant += gnttab_count_grant(sg->offset, sg->length); in blkif_queue_rw_req()
760 require_extra_req = info->max_indirect_segments == 0 && in blkif_queue_rw_req()
764 rinfo->shadow[id].num_sg = num_sg; in blkif_queue_rw_req()
771 BUG_ON(req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA); in blkif_queue_rw_req()
772 ring_req->operation = BLKIF_OP_INDIRECT; in blkif_queue_rw_req()
773 ring_req->u.indirect.indirect_op = rq_data_dir(req) ? in blkif_queue_rw_req()
775 ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req); in blkif_queue_rw_req()
776 ring_req->u.indirect.handle = info->handle; in blkif_queue_rw_req()
777 ring_req->u.indirect.nr_segments = num_grant; in blkif_queue_rw_req()
779 ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req); in blkif_queue_rw_req()
780 ring_req->u.rw.handle = info->handle; in blkif_queue_rw_req()
781 ring_req->operation = rq_data_dir(req) ? in blkif_queue_rw_req()
784 (req_op(req) == REQ_OP_WRITE && (req->cmd_flags & REQ_FUA))) { in blkif_queue_rw_req()
786 * Ideally we can do an unordered flush-to-disk. in blkif_queue_rw_req()
794 * run-time disabled after a failing I/O, and we'll in blkif_queue_rw_req()
797 if (info->feature_flush && info->feature_fua) in blkif_queue_rw_req()
798 ring_req->operation = in blkif_queue_rw_req()
800 else if (info->feature_flush) in blkif_queue_rw_req()
801 ring_req->operation = in blkif_queue_rw_req()
804 ring_req->u.rw.nr_segments = num_grant; in blkif_queue_rw_req()
808 extra_ring_req = &rinfo->shadow[extra_id].req; in blkif_queue_rw_req()
811 * Only the first request contains the scatter-gather in blkif_queue_rw_req()
814 rinfo->shadow[extra_id].num_sg = 0; in blkif_queue_rw_req()
819 rinfo->shadow[extra_id].associated_id = id; in blkif_queue_rw_req()
820 rinfo->shadow[id].associated_id = extra_id; in blkif_queue_rw_req()
831 for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i) { in blkif_queue_rw_req()
832 BUG_ON(sg->offset + sg->length > PAGE_SIZE); in blkif_queue_rw_req()
835 setup.bvec_off = sg->offset; in blkif_queue_rw_req()
840 sg->offset, in blkif_queue_rw_req()
841 sg->length, in blkif_queue_rw_req()
853 rinfo->shadow[id].status = REQ_WAITING; in blkif_queue_rw_req()
856 rinfo->shadow[extra_id].status = REQ_WAITING; in blkif_queue_rw_req()
866 * Generate a Xen blkfront IO request from a blk layer request. Reads
873 if (unlikely(rinfo->dev_info->connected != BLKIF_STATE_CONNECTED)) in blkif_queue_request()
887 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&rinfo->ring, notify); in flush_requests()
890 notify_remote_via_irq(rinfo->irq); in flush_requests()
897 int qid = hctx->queue_num; in blkif_queue_rq()
898 struct blkfront_info *info = hctx->queue->queuedata; in blkif_queue_rq()
902 blk_mq_start_request(qd->rq); in blkif_queue_rq()
903 spin_lock_irqsave(&rinfo->ring_lock, flags); in blkif_queue_rq()
915 if (unlikely(req_op(qd->rq) == REQ_OP_FLUSH && !info->feature_flush)) in blkif_queue_rq()
918 if (RING_FULL(&rinfo->ring)) in blkif_queue_rq()
920 if (blkif_queue_request(qd->rq, rinfo)) in blkif_queue_rq()
924 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in blkif_queue_rq()
929 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in blkif_queue_rq()
932 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in blkif_queue_rq()
933 blk_mq_end_request(qd->rq, BLK_STS_OK); in blkif_queue_rq()
939 blk_mq_end_request(rq, blkif_req(rq)->error); in blkif_complete_rq()
950 unsigned int segments = info->max_indirect_segments ? : in blkif_set_queue_limits()
953 if (info->feature_discard) { in blkif_set_queue_limits()
954 lim->max_hw_discard_sectors = UINT_MAX; in blkif_set_queue_limits()
955 if (info->discard_granularity) in blkif_set_queue_limits()
956 lim->discard_granularity = info->discard_granularity; in blkif_set_queue_limits()
957 lim->discard_alignment = info->discard_alignment; in blkif_set_queue_limits()
958 if (info->feature_secdiscard) in blkif_set_queue_limits()
959 lim->max_secure_erase_sectors = UINT_MAX; in blkif_set_queue_limits()
962 if (info->feature_flush) { in blkif_set_queue_limits()
963 lim->features |= BLK_FEAT_WRITE_CACHE; in blkif_set_queue_limits()
964 if (info->feature_fua) in blkif_set_queue_limits()
965 lim->features |= BLK_FEAT_FUA; in blkif_set_queue_limits()
969 lim->logical_block_size = info->sector_size; in blkif_set_queue_limits()
970 lim->physical_block_size = info->physical_sector_size; in blkif_set_queue_limits()
971 lim->max_hw_sectors = (segments * XEN_PAGE_SIZE) / 512; in blkif_set_queue_limits()
974 lim->seg_boundary_mask = PAGE_SIZE - 1; in blkif_set_queue_limits()
975 lim->max_segment_size = PAGE_SIZE; in blkif_set_queue_limits()
978 lim->max_segments = segments / GRANTS_PER_PSEG; in blkif_set_queue_limits()
980 /* Make sure buffer addresses are sector-aligned. */ in blkif_set_queue_limits()
981 lim->dma_alignment = 511; in blkif_set_queue_limits()
986 if (info->feature_flush && info->feature_fua) in flush_info()
988 else if (info->feature_flush) in flush_info()
997 info->gd->disk_name, flush_info(info), in xlvbd_flush()
998 "persistent grants:", info->feature_persistent ? in xlvbd_flush()
1000 info->max_indirect_segments ? "enabled;" : "disabled;", in xlvbd_flush()
1001 "bounce buffer:", info->bounce ? "enabled" : "disabled;"); in xlvbd_flush()
1032 ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) + in xen_translate_vdev()
1035 ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16 * PARTS_PER_DISK) + in xen_translate_vdev()
1047 ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) + in xen_translate_vdev()
1050 ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16 * PARTS_PER_DISK) + in xen_translate_vdev()
1059 return -ENODEV; in xen_translate_vdev()
1067 ptr = encode_disk_name(ptr, n / 26 - 1); in encode_disk_name()
1084 BUG_ON(info->gd != NULL); in xlvbd_alloc_gendisk()
1085 BUG_ON(info->rq != NULL); in xlvbd_alloc_gendisk()
1087 if ((info->vdevice>>EXT_SHIFT) > 1) { in xlvbd_alloc_gendisk()
1089 …printk(KERN_WARNING "blkfront: vdevice 0x%x is above the extended range; ignoring\n", info->vdevic… in xlvbd_alloc_gendisk()
1090 return -ENODEV; in xlvbd_alloc_gendisk()
1093 if (!VDEV_IS_EXTENDED(info->vdevice)) { in xlvbd_alloc_gendisk()
1094 err = xen_translate_vdev(info->vdevice, &minor, &offset); in xlvbd_alloc_gendisk()
1099 minor = BLKIF_MINOR_EXT(info->vdevice); in xlvbd_alloc_gendisk()
1105 "from xvde on\n", info->vdevice); in xlvbd_alloc_gendisk()
1109 info->vdevice, minor); in xlvbd_alloc_gendisk()
1110 return -ENODEV; in xlvbd_alloc_gendisk()
1120 memset(&info->tag_set, 0, sizeof(info->tag_set)); in xlvbd_alloc_gendisk()
1121 info->tag_set.ops = &blkfront_mq_ops; in xlvbd_alloc_gendisk()
1122 info->tag_set.nr_hw_queues = info->nr_rings; in xlvbd_alloc_gendisk()
1123 if (HAS_EXTRA_REQ && info->max_indirect_segments == 0) { in xlvbd_alloc_gendisk()
1130 info->tag_set.queue_depth = BLK_RING_SIZE(info) / 2; in xlvbd_alloc_gendisk()
1132 info->tag_set.queue_depth = BLK_RING_SIZE(info); in xlvbd_alloc_gendisk()
1133 info->tag_set.numa_node = NUMA_NO_NODE; in xlvbd_alloc_gendisk()
1134 info->tag_set.cmd_size = sizeof(struct blkif_req); in xlvbd_alloc_gendisk()
1135 info->tag_set.driver_data = info; in xlvbd_alloc_gendisk()
1137 err = blk_mq_alloc_tag_set(&info->tag_set); in xlvbd_alloc_gendisk()
1142 gd = blk_mq_alloc_disk(&info->tag_set, &lim, info); in xlvbd_alloc_gendisk()
1148 strcpy(gd->disk_name, DEV_NAME); in xlvbd_alloc_gendisk()
1149 ptr = encode_disk_name(gd->disk_name + sizeof(DEV_NAME) - 1, offset); in xlvbd_alloc_gendisk()
1150 BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN); in xlvbd_alloc_gendisk()
1154 snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr, in xlvbd_alloc_gendisk()
1155 "%d", minor & (nr_parts - 1)); in xlvbd_alloc_gendisk()
1157 gd->major = XENVBD_MAJOR; in xlvbd_alloc_gendisk()
1158 gd->first_minor = minor; in xlvbd_alloc_gendisk()
1159 gd->minors = nr_minors; in xlvbd_alloc_gendisk()
1160 gd->fops = &xlvbd_block_fops; in xlvbd_alloc_gendisk()
1161 gd->private_data = info; in xlvbd_alloc_gendisk()
1164 info->rq = gd->queue; in xlvbd_alloc_gendisk()
1165 info->gd = gd; in xlvbd_alloc_gendisk()
1169 if (info->vdisk_info & VDISK_READONLY) in xlvbd_alloc_gendisk()
1171 if (info->vdisk_info & VDISK_REMOVABLE) in xlvbd_alloc_gendisk()
1172 gd->flags |= GENHD_FL_REMOVABLE; in xlvbd_alloc_gendisk()
1177 blk_mq_free_tag_set(&info->tag_set); in xlvbd_alloc_gendisk()
1183 /* Already hold rinfo->ring_lock. */
1186 if (!RING_FULL(&rinfo->ring)) in kick_pending_request_queues_locked()
1187 blk_mq_start_stopped_hw_queues(rinfo->dev_info->rq, true); in kick_pending_request_queues_locked()
1194 spin_lock_irqsave(&rinfo->ring_lock, flags); in kick_pending_request_queues()
1196 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in kick_pending_request_queues()
1203 if (rinfo->dev_info->connected == BLKIF_STATE_CONNECTED) in blkif_restart_queue()
1210 struct blkfront_info *info = rinfo->dev_info; in blkif_free_ring()
1217 if (!list_empty(&rinfo->indirect_pages)) { in blkif_free_ring()
1220 BUG_ON(info->bounce); in blkif_free_ring()
1221 list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { in blkif_free_ring()
1222 list_del(&indirect_page->lru); in blkif_free_ring()
1228 if (!list_empty(&rinfo->grants)) { in blkif_free_ring()
1230 &rinfo->grants, node) { in blkif_free_ring()
1231 list_del(&persistent_gnt->node); in blkif_free_ring()
1232 if (persistent_gnt->gref != INVALID_GRANT_REF) { in blkif_free_ring()
1233 gnttab_end_foreign_access(persistent_gnt->gref, in blkif_free_ring()
1235 rinfo->persistent_gnts_c--; in blkif_free_ring()
1237 if (info->bounce) in blkif_free_ring()
1238 __free_page(persistent_gnt->page); in blkif_free_ring()
1242 BUG_ON(rinfo->persistent_gnts_c != 0); in blkif_free_ring()
1249 if (!rinfo->shadow[i].request) in blkif_free_ring()
1252 segs = rinfo->shadow[i].req.operation == BLKIF_OP_INDIRECT ? in blkif_free_ring()
1253 rinfo->shadow[i].req.u.indirect.nr_segments : in blkif_free_ring()
1254 rinfo->shadow[i].req.u.rw.nr_segments; in blkif_free_ring()
1256 persistent_gnt = rinfo->shadow[i].grants_used[j]; in blkif_free_ring()
1257 gnttab_end_foreign_access(persistent_gnt->gref, NULL); in blkif_free_ring()
1258 if (info->bounce) in blkif_free_ring()
1259 __free_page(persistent_gnt->page); in blkif_free_ring()
1263 if (rinfo->shadow[i].req.operation != BLKIF_OP_INDIRECT) in blkif_free_ring()
1271 persistent_gnt = rinfo->shadow[i].indirect_grants[j]; in blkif_free_ring()
1272 gnttab_end_foreign_access(persistent_gnt->gref, NULL); in blkif_free_ring()
1273 __free_page(persistent_gnt->page); in blkif_free_ring()
1278 kvfree(rinfo->shadow[i].grants_used); in blkif_free_ring()
1279 rinfo->shadow[i].grants_used = NULL; in blkif_free_ring()
1280 kvfree(rinfo->shadow[i].indirect_grants); in blkif_free_ring()
1281 rinfo->shadow[i].indirect_grants = NULL; in blkif_free_ring()
1282 kvfree(rinfo->shadow[i].sg); in blkif_free_ring()
1283 rinfo->shadow[i].sg = NULL; in blkif_free_ring()
1287 gnttab_cancel_free_callback(&rinfo->callback); in blkif_free_ring()
1290 flush_work(&rinfo->work); in blkif_free_ring()
1293 xenbus_teardown_ring((void **)&rinfo->ring.sring, info->nr_ring_pages, in blkif_free_ring()
1294 rinfo->ring_ref); in blkif_free_ring()
1296 if (rinfo->irq) in blkif_free_ring()
1297 unbind_from_irqhandler(rinfo->irq, rinfo); in blkif_free_ring()
1298 rinfo->evtchn = rinfo->irq = 0; in blkif_free_ring()
1307 info->connected = suspend ? in blkif_free()
1310 if (info->rq) in blkif_free()
1311 blk_mq_stop_hw_queues(info->rq); in blkif_free()
1316 kvfree(info->rinfo); in blkif_free()
1317 info->rinfo = NULL; in blkif_free()
1318 info->nr_rings = 0; in blkif_free()
1334 const struct blk_shadow *s = info->s; in blkif_copy_from_grant()
1336 shared_data = kmap_atomic(s->grants_used[info->grant_idx]->page); in blkif_copy_from_grant()
1338 memcpy(info->bvec_data + info->bvec_offset, in blkif_copy_from_grant()
1341 info->bvec_offset += len; in blkif_copy_from_grant()
1342 info->grant_idx++; in blkif_copy_from_grant()
1381 * -1 error while processing.
1390 struct blkfront_info *info = rinfo->dev_info; in blkif_completion()
1391 struct blk_shadow *s = &rinfo->shadow[*id]; in blkif_completion()
1396 num_grant = s->req.operation == BLKIF_OP_INDIRECT ? in blkif_completion()
1397 s->req.u.indirect.nr_segments : s->req.u.rw.nr_segments; in blkif_completion()
1400 if (unlikely(s->associated_id != NO_ASSOCIATED_ID)) { in blkif_completion()
1401 struct blk_shadow *s2 = &rinfo->shadow[s->associated_id]; in blkif_completion()
1404 s->status = blkif_rsp_to_req_status(bret->status); in blkif_completion()
1407 if (s2->status < REQ_DONE) in blkif_completion()
1410 bret->status = blkif_get_final_status(s->status, in blkif_completion()
1411 s2->status); in blkif_completion()
1417 num_grant += s2->req.u.rw.nr_segments; in blkif_completion()
1421 * first request will store the scatter-gather list. in blkif_completion()
1423 if (s2->num_sg != 0) { in blkif_completion()
1425 *id = s->associated_id; in blkif_completion()
1433 if (add_id_to_freelist(rinfo, s->associated_id)) in blkif_completion()
1435 info->gd->disk_name, s->associated_id); in blkif_completion()
1439 num_sg = s->num_sg; in blkif_completion()
1441 if (bret->operation == BLKIF_OP_READ && info->bounce) { in blkif_completion()
1442 for_each_sg(s->sg, sg, num_sg, i) { in blkif_completion()
1443 BUG_ON(sg->offset + sg->length > PAGE_SIZE); in blkif_completion()
1445 data.bvec_offset = sg->offset; in blkif_completion()
1449 sg->offset, in blkif_completion()
1450 sg->length, in blkif_completion()
1459 if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) { in blkif_completion()
1466 if (!info->feature_persistent) { in blkif_completion()
1468 s->grants_used[i]->gref); in blkif_completion()
1469 return -1; in blkif_completion()
1471 list_add(&s->grants_used[i]->node, &rinfo->grants); in blkif_completion()
1472 rinfo->persistent_gnts_c++; in blkif_completion()
1479 s->grants_used[i]->gref = INVALID_GRANT_REF; in blkif_completion()
1480 list_add_tail(&s->grants_used[i]->node, &rinfo->grants); in blkif_completion()
1483 if (s->req.operation == BLKIF_OP_INDIRECT) { in blkif_completion()
1485 if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) { in blkif_completion()
1486 if (!info->feature_persistent) { in blkif_completion()
1488 s->indirect_grants[i]->gref); in blkif_completion()
1489 return -1; in blkif_completion()
1491 list_add(&s->indirect_grants[i]->node, &rinfo->grants); in blkif_completion()
1492 rinfo->persistent_gnts_c++; in blkif_completion()
1500 if (!info->bounce) { in blkif_completion()
1501 indirect_page = s->indirect_grants[i]->page; in blkif_completion()
1502 list_add(&indirect_page->lru, &rinfo->indirect_pages); in blkif_completion()
1504 s->indirect_grants[i]->gref = INVALID_GRANT_REF; in blkif_completion()
1505 list_add_tail(&s->indirect_grants[i]->node, &rinfo->grants); in blkif_completion()
1520 struct blkfront_info *info = rinfo->dev_info; in blkif_interrupt()
1523 if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { in blkif_interrupt()
1528 spin_lock_irqsave(&rinfo->ring_lock, flags); in blkif_interrupt()
1530 rp = READ_ONCE(rinfo->ring.sring->rsp_prod); in blkif_interrupt()
1532 if (RING_RESPONSE_PROD_OVERFLOW(&rinfo->ring, rp)) { in blkif_interrupt()
1534 info->gd->disk_name, rp - rinfo->ring.rsp_cons); in blkif_interrupt()
1538 for (i = rinfo->ring.rsp_cons; i != rp; i++) { in blkif_interrupt()
1544 RING_COPY_RESPONSE(&rinfo->ring, i, &bret); in blkif_interrupt()
1549 * never have given to it (we stamp it up to BLK_RING_SIZE - in blkif_interrupt()
1554 info->gd->disk_name, id); in blkif_interrupt()
1557 if (rinfo->shadow[id].status != REQ_WAITING) { in blkif_interrupt()
1559 info->gd->disk_name); in blkif_interrupt()
1563 rinfo->shadow[id].status = REQ_PROCESSING; in blkif_interrupt()
1564 req = rinfo->shadow[id].request; in blkif_interrupt()
1566 op = rinfo->shadow[id].req.operation; in blkif_interrupt()
1568 op = rinfo->shadow[id].req.u.indirect.indirect_op; in blkif_interrupt()
1571 info->gd->disk_name, bret.operation, op); in blkif_interrupt()
1591 info->gd->disk_name, op_name(bret.operation), id); in blkif_interrupt()
1596 blkif_req(req)->error = BLK_STS_OK; in blkif_interrupt()
1598 blkif_req(req)->error = BLK_STS_IOERR; in blkif_interrupt()
1603 struct request_queue *rq = info->rq; in blkif_interrupt()
1606 info->gd->disk_name, op_name(bret.operation)); in blkif_interrupt()
1607 blkif_req(req)->error = BLK_STS_NOTSUPP; in blkif_interrupt()
1608 info->feature_discard = 0; in blkif_interrupt()
1609 info->feature_secdiscard = 0; in blkif_interrupt()
1618 info->gd->disk_name, op_name(bret.operation)); in blkif_interrupt()
1619 blkif_req(req)->error = BLK_STS_NOTSUPP; in blkif_interrupt()
1622 rinfo->shadow[id].req.u.rw.nr_segments == 0)) { in blkif_interrupt()
1624 info->gd->disk_name, op_name(bret.operation)); in blkif_interrupt()
1625 blkif_req(req)->error = BLK_STS_NOTSUPP; in blkif_interrupt()
1627 if (unlikely(blkif_req(req)->error)) { in blkif_interrupt()
1628 if (blkif_req(req)->error == BLK_STS_NOTSUPP) in blkif_interrupt()
1629 blkif_req(req)->error = BLK_STS_OK; in blkif_interrupt()
1630 info->feature_fua = 0; in blkif_interrupt()
1631 info->feature_flush = 0; in blkif_interrupt()
1637 dev_dbg_ratelimited(&info->xbdev->dev, in blkif_interrupt()
1646 if (likely(!blk_should_fake_timeout(req->q))) in blkif_interrupt()
1650 rinfo->ring.rsp_cons = i; in blkif_interrupt()
1652 if (i != rinfo->ring.req_prod_pvt) { in blkif_interrupt()
1654 RING_FINAL_CHECK_FOR_RESPONSES(&rinfo->ring, more_to_do); in blkif_interrupt()
1658 rinfo->ring.sring->rsp_event = i + 1; in blkif_interrupt()
1662 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in blkif_interrupt()
1669 info->connected = BLKIF_STATE_ERROR; in blkif_interrupt()
1671 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in blkif_interrupt()
1675 pr_alert("%s disabled for further use\n", info->gd->disk_name); in blkif_interrupt()
1685 struct blkfront_info *info = rinfo->dev_info; in setup_blkring()
1686 unsigned long ring_size = info->nr_ring_pages * XEN_PAGE_SIZE; in setup_blkring()
1689 info->nr_ring_pages, rinfo->ring_ref); in setup_blkring()
1693 XEN_FRONT_RING_INIT(&rinfo->ring, sring, ring_size); in setup_blkring()
1695 err = xenbus_alloc_evtchn(dev, &rinfo->evtchn); in setup_blkring()
1699 err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt, in setup_blkring()
1706 rinfo->irq = err; in setup_blkring()
1715 * Write out per-ring/queue nodes including ring-ref and event-channel, and each
1716 * ring buffer may have multi pages depending on ->nr_ring_pages.
1724 struct blkfront_info *info = rinfo->dev_info; in write_per_ring_nodes()
1726 if (info->nr_ring_pages == 1) { in write_per_ring_nodes()
1727 err = xenbus_printf(xbt, dir, "ring-ref", "%u", rinfo->ring_ref[0]); in write_per_ring_nodes()
1729 message = "writing ring-ref"; in write_per_ring_nodes()
1733 for (i = 0; i < info->nr_ring_pages; i++) { in write_per_ring_nodes()
1736 snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); in write_per_ring_nodes()
1738 "%u", rinfo->ring_ref[i]); in write_per_ring_nodes()
1740 message = "writing ring-ref"; in write_per_ring_nodes()
1746 err = xenbus_printf(xbt, dir, "event-channel", "%u", rinfo->evtchn); in write_per_ring_nodes()
1748 message = "writing event-channel"; in write_per_ring_nodes()
1757 xenbus_dev_fatal(info->xbdev, err, "%s", message); in write_per_ring_nodes()
1780 return -ENODEV; in talk_to_blkback()
1783 info->bounce = !xen_blkif_trusted || in talk_to_blkback()
1784 !xenbus_read_unsigned(dev->nodename, "trusted", 1); in talk_to_blkback()
1786 max_page_order = xenbus_read_unsigned(info->xbdev->otherend, in talk_to_blkback()
1787 "max-ring-page-order", 0); in talk_to_blkback()
1789 info->nr_ring_pages = 1 << ring_page_order; in talk_to_blkback()
1809 if (info->nr_ring_pages > 1) { in talk_to_blkback()
1810 err = xenbus_printf(xbt, dev->nodename, "ring-page-order", "%u", in talk_to_blkback()
1813 message = "writing ring-page-order"; in talk_to_blkback()
1819 if (info->nr_rings == 1) { in talk_to_blkback()
1820 err = write_per_ring_nodes(xbt, info->rinfo, dev->nodename); in talk_to_blkback()
1827 err = xenbus_printf(xbt, dev->nodename, "multi-queue-num-queues", "%u", in talk_to_blkback()
1828 info->nr_rings); in talk_to_blkback()
1830 message = "writing multi-queue-num-queues"; in talk_to_blkback()
1834 pathsize = strlen(dev->nodename) + QUEUE_NAME_LEN; in talk_to_blkback()
1837 err = -ENOMEM; in talk_to_blkback()
1844 snprintf(path, pathsize, "%s/queue-%u", dev->nodename, i); in talk_to_blkback()
1853 err = xenbus_printf(xbt, dev->nodename, "protocol", "%s", in talk_to_blkback()
1859 info->feature_persistent_parm = feature_persistent; in talk_to_blkback()
1860 err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", in talk_to_blkback()
1861 info->feature_persistent_parm); in talk_to_blkback()
1863 dev_warn(&dev->dev, in talk_to_blkback()
1868 if (err == -EAGAIN) in talk_to_blkback()
1878 rinfo->shadow[j].req.u.rw.id = j + 1; in talk_to_blkback()
1879 rinfo->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff; in talk_to_blkback()
1900 BUG_ON(info->nr_rings); in negotiate_mq()
1903 backend_max_queues = xenbus_read_unsigned(info->xbdev->otherend, in negotiate_mq()
1904 "multi-queue-max-queues", 1); in negotiate_mq()
1905 info->nr_rings = min(backend_max_queues, xen_blkif_max_queues); in negotiate_mq()
1907 if (!info->nr_rings) in negotiate_mq()
1908 info->nr_rings = 1; in negotiate_mq()
1910 info->rinfo_size = struct_size(info->rinfo, shadow, in negotiate_mq()
1912 info->rinfo = kvcalloc(info->nr_rings, info->rinfo_size, GFP_KERNEL); in negotiate_mq()
1913 if (!info->rinfo) { in negotiate_mq()
1914 xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); in negotiate_mq()
1915 info->nr_rings = 0; in negotiate_mq()
1916 return -ENOMEM; in negotiate_mq()
1920 INIT_LIST_HEAD(&rinfo->indirect_pages); in negotiate_mq()
1921 INIT_LIST_HEAD(&rinfo->grants); in negotiate_mq()
1922 rinfo->dev_info = info; in negotiate_mq()
1923 INIT_WORK(&rinfo->work, blkif_restart_queue); in negotiate_mq()
1924 spin_lock_init(&rinfo->ring_lock); in negotiate_mq()
1942 err = xenbus_scanf(XBT_NIL, dev->nodename, in blkfront_probe()
1943 "virtual-device", "%i", &vdevice); in blkfront_probe()
1946 err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device-ext", in blkfront_probe()
1949 xenbus_dev_fatal(dev, err, "reading virtual-device"); in blkfront_probe()
1970 return -ENODEV; in blkfront_probe()
1974 type = xenbus_read(XBT_NIL, dev->nodename, "device-type", &len); in blkfront_probe()
1976 return -ENODEV; in blkfront_probe()
1979 return -ENODEV; in blkfront_probe()
1985 xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); in blkfront_probe()
1986 return -ENOMEM; in blkfront_probe()
1989 info->xbdev = dev; in blkfront_probe()
1991 mutex_init(&info->mutex); in blkfront_probe()
1992 info->vdevice = vdevice; in blkfront_probe()
1993 info->connected = BLKIF_STATE_DISCONNECTED; in blkfront_probe()
1996 info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); in blkfront_probe()
1997 dev_set_drvdata(&dev->dev, info); in blkfront_probe()
2000 list_add(&info->info_list, &info_list); in blkfront_probe()
2015 lim = queue_limits_start_update(info->rq); in blkif_recover()
2018 rc = queue_limits_commit_update(info->rq, &lim); in blkif_recover()
2027 xenbus_switch_state(info->xbdev, XenbusStateConnected); in blkif_recover()
2030 info->connected = BLKIF_STATE_CONNECTED; in blkif_recover()
2037 list_for_each_entry_safe(req, n, &info->requests, queuelist) { in blkif_recover()
2039 list_del_init(&req->queuelist); in blkif_recover()
2040 BUG_ON(req->nr_phys_segments > in blkif_recover()
2041 (info->max_indirect_segments ? : in blkif_recover()
2045 blk_mq_start_stopped_hw_queues(info->rq, true); in blkif_recover()
2046 blk_mq_kick_requeue_list(info->rq); in blkif_recover()
2048 while ((bio = bio_list_pop(&info->bio_list)) != NULL) { in blkif_recover()
2049 /* Traverse the list of pending bios and re-queue them */ in blkif_recover()
2059 * leave the device-layer structures intact so that this is transparent to the
2064 struct blkfront_info *info = dev_get_drvdata(&dev->dev); in blkfront_resume()
2069 dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename); in blkfront_resume()
2071 bio_list_init(&info->bio_list); in blkfront_resume()
2072 INIT_LIST_HEAD(&info->requests); in blkfront_resume()
2075 struct blk_shadow *shadow = rinfo->shadow; in blkfront_resume()
2083 * Get the bios in the request so we can re-queue them. in blkfront_resume()
2088 shadow[j].request->cmd_flags & REQ_FUA) { in blkfront_resume()
2096 list_add(&shadow[j].request->queuelist, &info->requests); in blkfront_resume()
2099 merge_bio.head = shadow[j].request->bio; in blkfront_resume()
2100 merge_bio.tail = shadow[j].request->biotail; in blkfront_resume()
2101 bio_list_merge(&info->bio_list, &merge_bio); in blkfront_resume()
2102 shadow[j].request->bio = NULL; in blkfront_resume()
2107 blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); in blkfront_resume()
2111 blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); in blkfront_resume()
2124 struct xenbus_device *xbdev = info->xbdev; in blkfront_closing()
2128 if (xbdev->state == XenbusStateClosing) in blkfront_closing()
2132 if (info->rq && info->gd) { in blkfront_closing()
2133 blk_mq_stop_hw_queues(info->rq); in blkfront_closing()
2134 blk_mark_disk_dead(info->gd); in blkfront_closing()
2139 gnttab_cancel_free_callback(&rinfo->callback); in blkfront_closing()
2142 flush_work(&rinfo->work); in blkfront_closing()
2150 info->feature_discard = 1; in blkfront_setup_discard()
2151 info->discard_granularity = xenbus_read_unsigned(info->xbdev->otherend, in blkfront_setup_discard()
2152 "discard-granularity", in blkfront_setup_discard()
2154 info->discard_alignment = xenbus_read_unsigned(info->xbdev->otherend, in blkfront_setup_discard()
2155 "discard-alignment", 0); in blkfront_setup_discard()
2156 info->feature_secdiscard = in blkfront_setup_discard()
2157 !!xenbus_read_unsigned(info->xbdev->otherend, "discard-secure", in blkfront_setup_discard()
2165 struct blkfront_info *info = rinfo->dev_info; in blkfront_setup_indirect()
2169 if (info->max_indirect_segments == 0) { in blkfront_setup_indirect()
2182 grants = info->max_indirect_segments; in blkfront_setup_indirect()
2190 if (!info->bounce && info->max_indirect_segments) { in blkfront_setup_indirect()
2198 BUG_ON(!list_empty(&rinfo->indirect_pages)); in blkfront_setup_indirect()
2204 list_add(&indirect_page->lru, &rinfo->indirect_pages); in blkfront_setup_indirect()
2209 rinfo->shadow[i].grants_used = in blkfront_setup_indirect()
2211 sizeof(rinfo->shadow[i].grants_used[0]), in blkfront_setup_indirect()
2213 rinfo->shadow[i].sg = kvcalloc(psegs, in blkfront_setup_indirect()
2214 sizeof(rinfo->shadow[i].sg[0]), in blkfront_setup_indirect()
2216 if (info->max_indirect_segments) in blkfront_setup_indirect()
2217 rinfo->shadow[i].indirect_grants = in blkfront_setup_indirect()
2219 sizeof(rinfo->shadow[i].indirect_grants[0]), in blkfront_setup_indirect()
2221 if ((rinfo->shadow[i].grants_used == NULL) || in blkfront_setup_indirect()
2222 (rinfo->shadow[i].sg == NULL) || in blkfront_setup_indirect()
2223 (info->max_indirect_segments && in blkfront_setup_indirect()
2224 (rinfo->shadow[i].indirect_grants == NULL))) in blkfront_setup_indirect()
2226 sg_init_table(rinfo->shadow[i].sg, psegs); in blkfront_setup_indirect()
2235 kvfree(rinfo->shadow[i].grants_used); in blkfront_setup_indirect()
2236 rinfo->shadow[i].grants_used = NULL; in blkfront_setup_indirect()
2237 kvfree(rinfo->shadow[i].sg); in blkfront_setup_indirect()
2238 rinfo->shadow[i].sg = NULL; in blkfront_setup_indirect()
2239 kvfree(rinfo->shadow[i].indirect_grants); in blkfront_setup_indirect()
2240 rinfo->shadow[i].indirect_grants = NULL; in blkfront_setup_indirect()
2242 if (!list_empty(&rinfo->indirect_pages)) { in blkfront_setup_indirect()
2244 list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { in blkfront_setup_indirect()
2245 list_del(&indirect_page->lru); in blkfront_setup_indirect()
2252 return -ENOMEM; in blkfront_setup_indirect()
2256 * Gather all backend feature-*
2262 info->feature_flush = 0; in blkfront_gather_backend_features()
2263 info->feature_fua = 0; in blkfront_gather_backend_features()
2266 * If there's no "feature-barrier" defined, then it means in blkfront_gather_backend_features()
2272 if (xenbus_read_unsigned(info->xbdev->otherend, "feature-barrier", 0)) { in blkfront_gather_backend_features()
2273 info->feature_flush = 1; in blkfront_gather_backend_features()
2274 info->feature_fua = 1; in blkfront_gather_backend_features()
2278 * And if there is "feature-flush-cache" use that above in blkfront_gather_backend_features()
2281 if (xenbus_read_unsigned(info->xbdev->otherend, "feature-flush-cache", in blkfront_gather_backend_features()
2283 info->feature_flush = 1; in blkfront_gather_backend_features()
2284 info->feature_fua = 0; in blkfront_gather_backend_features()
2287 if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0)) in blkfront_gather_backend_features()
2290 if (info->feature_persistent_parm) in blkfront_gather_backend_features()
2291 info->feature_persistent = in blkfront_gather_backend_features()
2292 !!xenbus_read_unsigned(info->xbdev->otherend, in blkfront_gather_backend_features()
2293 "feature-persistent", 0); in blkfront_gather_backend_features()
2294 if (info->feature_persistent) in blkfront_gather_backend_features()
2295 info->bounce = true; in blkfront_gather_backend_features()
2297 indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, in blkfront_gather_backend_features()
2298 "feature-max-indirect-segments", 0); in blkfront_gather_backend_features()
2303 info->max_indirect_segments = indirect_segments; in blkfront_gather_backend_features()
2305 if (info->feature_persistent) { in blkfront_gather_backend_features()
2314 * the details about the physical device - #sectors, size, etc).
2322 switch (info->connected) { in blkfront_connect()
2325 * Potentially, the back-end may be signalling in blkfront_connect()
2328 err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, in blkfront_connect()
2334 set_capacity_and_notify(info->gd, sectors); in blkfront_connect()
2351 dev_dbg(&info->xbdev->dev, "%s:%s.\n", in blkfront_connect()
2352 __func__, info->xbdev->otherend); in blkfront_connect()
2354 err = xenbus_gather(XBT_NIL, info->xbdev->otherend, in blkfront_connect()
2356 "info", "%u", &info->vdisk_info, in blkfront_connect()
2357 "sector-size", "%lu", &info->sector_size, in blkfront_connect()
2360 xenbus_dev_fatal(info->xbdev, err, in blkfront_connect()
2362 info->xbdev->otherend); in blkfront_connect()
2367 * physical-sector-size is a newer field, so old backends may not in blkfront_connect()
2371 info->physical_sector_size = xenbus_read_unsigned(info->xbdev->otherend, in blkfront_connect()
2372 "physical-sector-size", in blkfront_connect()
2373 info->sector_size); in blkfront_connect()
2378 xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s", in blkfront_connect()
2379 info->xbdev->otherend); in blkfront_connect()
2387 xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", in blkfront_connect()
2388 info->xbdev->otherend); in blkfront_connect()
2392 xenbus_switch_state(info->xbdev, XenbusStateConnected); in blkfront_connect()
2395 info->connected = BLKIF_STATE_CONNECTED; in blkfront_connect()
2399 err = device_add_disk(&info->xbdev->dev, info->gd, NULL); in blkfront_connect()
2401 put_disk(info->gd); in blkfront_connect()
2402 blk_mq_free_tag_set(&info->tag_set); in blkfront_connect()
2403 info->rq = NULL; in blkfront_connect()
2407 info->is_ready = 1; in blkfront_connect()
2421 struct blkfront_info *info = dev_get_drvdata(&dev->dev); in blkback_changed()
2423 dev_dbg(&dev->dev, "blkfront:blkback_changed to state %d.\n", backend_state); in blkback_changed()
2427 if (dev->state != XenbusStateInitialising) in blkback_changed()
2446 * state (and re-trigger the watch by setting the state repeatedly in blkback_changed()
2451 if ((dev->state != XenbusStateInitialised) && in blkback_changed()
2452 (dev->state != XenbusStateConnected)) { in blkback_changed()
2461 if (dev->state == XenbusStateClosed) in blkback_changed()
2472 struct blkfront_info *info = dev_get_drvdata(&xbdev->dev); in blkfront_remove()
2474 dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); in blkfront_remove()
2476 if (info->gd) in blkfront_remove()
2477 del_gendisk(info->gd); in blkfront_remove()
2480 list_del(&info->info_list); in blkfront_remove()
2484 if (info->gd) { in blkfront_remove()
2485 xlbd_release_minors(info->gd->first_minor, info->gd->minors); in blkfront_remove()
2486 put_disk(info->gd); in blkfront_remove()
2487 blk_mq_free_tag_set(&info->tag_set); in blkfront_remove()
2495 struct blkfront_info *info = dev_get_drvdata(&dev->dev); in blkfront_is_ready()
2497 return info->is_ready && info->xbdev; in blkfront_is_ready()
2533 spin_lock_irqsave(&rinfo->ring_lock, flags); in purge_persistent_grants()
2535 if (rinfo->persistent_gnts_c == 0) { in purge_persistent_grants()
2536 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in purge_persistent_grants()
2540 list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants, in purge_persistent_grants()
2542 if (gnt_list_entry->gref == INVALID_GRANT_REF || in purge_persistent_grants()
2543 !gnttab_try_end_foreign_access(gnt_list_entry->gref)) in purge_persistent_grants()
2546 list_del(&gnt_list_entry->node); in purge_persistent_grants()
2547 rinfo->persistent_gnts_c--; in purge_persistent_grants()
2548 gnt_list_entry->gref = INVALID_GRANT_REF; in purge_persistent_grants()
2549 list_add_tail(&gnt_list_entry->node, &grants); in purge_persistent_grants()
2552 list_splice_tail(&grants, &rinfo->grants); in purge_persistent_grants()
2554 spin_unlock_irqrestore(&rinfo->ring_lock, flags); in purge_persistent_grants()
2573 if (info->feature_persistent) { in blkfront_delay_work()
2575 mutex_lock(&info->mutex); in blkfront_delay_work()
2577 mutex_unlock(&info->mutex); in blkfront_delay_work()
2593 return -ENODEV; in xlblk_init()
2596 return -ENODEV; in xlblk_init()
2601 return -ENODEV; in xlblk_init()