Lines Matching +full:host +full:- +full:id

96 #define RSLT_RESET_ERR		-1
106 struct Scsi_Host *host; member
120 /* Following items are protected by the host lock. */
136 info->wait_ring_available = 0; in scsifront_wake_up()
137 wake_up(&info->wq_sync); in scsifront_wake_up()
145 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_get_rqid()
147 free = find_first_bit(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in scsifront_get_rqid()
148 __clear_bit(free, info->shadow_free_bitmap); in scsifront_get_rqid()
150 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_get_rqid()
155 static int _scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id) in _scsifront_put_rqid() argument
157 int empty = bitmap_empty(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in _scsifront_put_rqid()
159 __set_bit(id, info->shadow_free_bitmap); in _scsifront_put_rqid()
160 info->shadow[id] = NULL; in _scsifront_put_rqid()
162 return empty || info->wait_ring_available; in _scsifront_put_rqid()
165 static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id) in scsifront_put_rqid() argument
170 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_put_rqid()
171 kick = _scsifront_put_rqid(info, id); in scsifront_put_rqid()
172 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_put_rqid()
181 struct vscsiif_front_ring *ring = &(info->ring); in scsifront_do_request()
183 struct scsi_cmnd *sc = shadow->sc; in scsifront_do_request()
184 uint32_t id; in scsifront_do_request() local
187 if (RING_FULL(&info->ring)) in scsifront_do_request()
188 return -EBUSY; in scsifront_do_request()
190 id = scsifront_get_rqid(info); /* use id in response */ in scsifront_do_request()
191 if (id >= VSCSIIF_MAX_REQS) in scsifront_do_request()
192 return -EBUSY; in scsifront_do_request()
194 info->shadow[id] = shadow; in scsifront_do_request()
195 shadow->rqid = id; in scsifront_do_request()
197 ring_req = RING_GET_REQUEST(&(info->ring), ring->req_prod_pvt); in scsifront_do_request()
198 ring->req_prod_pvt++; in scsifront_do_request()
200 ring_req->rqid = id; in scsifront_do_request()
201 ring_req->act = shadow->act; in scsifront_do_request()
202 ring_req->ref_rqid = shadow->ref_rqid; in scsifront_do_request()
203 ring_req->nr_segments = shadow->nr_segments; in scsifront_do_request()
205 ring_req->id = sc->device->id; in scsifront_do_request()
206 ring_req->lun = sc->device->lun; in scsifront_do_request()
207 ring_req->channel = sc->device->channel; in scsifront_do_request()
208 ring_req->cmd_len = sc->cmd_len; in scsifront_do_request()
210 BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE); in scsifront_do_request()
212 memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len); in scsifront_do_request()
214 ring_req->sc_data_direction = (uint8_t)sc->sc_data_direction; in scsifront_do_request()
215 ring_req->timeout_per_command = scsi_cmd_to_rq(sc)->timeout / HZ; in scsifront_do_request()
217 for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++) in scsifront_do_request()
218 ring_req->seg[i] = shadow->seg[i]; in scsifront_do_request()
222 notify_remote_via_irq(info->irq); in scsifront_do_request()
232 if (shadow->sc->sc_data_direction == DMA_NONE) in scsifront_gnttab_done()
235 for (i = 0; i < shadow->nr_grants; i++) { in scsifront_gnttab_done()
236 if (unlikely(gnttab_query_foreign_access(shadow->gref[i]))) { in scsifront_gnttab_done()
237 shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME in scsifront_gnttab_done()
241 gnttab_end_foreign_access(shadow->gref[i], 0, 0UL); in scsifront_gnttab_done()
244 kfree(shadow->sg); in scsifront_gnttab_done()
252 uint32_t id; in scsifront_cdb_cmd_done() local
256 id = ring_rsp->rqid; in scsifront_cdb_cmd_done()
257 shadow = info->shadow[id]; in scsifront_cdb_cmd_done()
258 sc = shadow->sc; in scsifront_cdb_cmd_done()
263 scsifront_put_rqid(info, id); in scsifront_cdb_cmd_done()
265 result = ring_rsp->rslt; in scsifront_cdb_cmd_done()
271 scsi_set_resid(sc, ring_rsp->residual_len); in scsifront_cdb_cmd_done()
274 ring_rsp->sense_len); in scsifront_cdb_cmd_done()
277 memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len); in scsifront_cdb_cmd_done()
279 sc->scsi_done(sc); in scsifront_cdb_cmd_done()
285 uint16_t id = ring_rsp->rqid; in scsifront_sync_cmd_done() local
287 struct vscsifrnt_shadow *shadow = info->shadow[id]; in scsifront_sync_cmd_done()
290 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
291 shadow->wait_reset = 1; in scsifront_sync_cmd_done()
292 switch (shadow->rslt_reset) { in scsifront_sync_cmd_done()
294 shadow->rslt_reset = ring_rsp->rslt; in scsifront_sync_cmd_done()
297 kick = _scsifront_put_rqid(info, id); in scsifront_sync_cmd_done()
298 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
304 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME in scsifront_sync_cmd_done()
306 shadow->rslt_reset, id); in scsifront_sync_cmd_done()
309 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
311 wake_up(&shadow->wq_reset); in scsifront_sync_cmd_done()
317 if (WARN(ring_rsp->rqid >= VSCSIIF_MAX_REQS || in scsifront_do_response()
318 test_bit(ring_rsp->rqid, info->shadow_free_bitmap), in scsifront_do_response()
319 "illegal rqid %u returned by backend!\n", ring_rsp->rqid)) in scsifront_do_response()
322 if (info->shadow[ring_rsp->rqid]->act == VSCSIIF_ACT_SCSI_CDB) in scsifront_do_response()
334 rp = info->ring.sring->rsp_prod; in scsifront_ring_drain()
336 for (i = info->ring.rsp_cons; i != rp; i++) { in scsifront_ring_drain()
337 ring_rsp = RING_GET_RESPONSE(&info->ring, i); in scsifront_ring_drain()
341 info->ring.rsp_cons = i; in scsifront_ring_drain()
343 if (i != info->ring.req_prod_pvt) in scsifront_ring_drain()
344 RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do); in scsifront_ring_drain()
346 info->ring.sring->rsp_event = i + 1; in scsifront_ring_drain()
356 spin_lock_irqsave(info->host->host_lock, flags); in scsifront_cmd_done()
360 info->wait_ring_available = 0; in scsifront_cmd_done()
362 spin_unlock_irqrestore(info->host->host_lock, flags); in scsifront_cmd_done()
364 wake_up(&info->wq_sync); in scsifront_cmd_done()
388 if (test_bit(i, info->shadow_free_bitmap)) in scsifront_finish_all()
405 int grant_ro = (sc->sc_data_direction == DMA_TO_DEVICE); in map_data_for_request()
412 if (sc->sc_data_direction == DMA_NONE || !data_len) in map_data_for_request()
416 data_grants += PFN_UP(sg->offset + sg->length); in map_data_for_request()
419 if (data_grants > info->host->sg_tablesize) { in map_data_for_request()
420 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME in map_data_for_request()
422 return -E2BIG; in map_data_for_request()
425 shadow->sg = kcalloc(data_grants, in map_data_for_request()
427 if (!shadow->sg) in map_data_for_request()
428 return -ENOMEM; in map_data_for_request()
430 seg = shadow->sg ? : shadow->seg; in map_data_for_request()
435 kfree(shadow->sg); in map_data_for_request()
436 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME in map_data_for_request()
438 return -ENOMEM; in map_data_for_request()
446 bytes = min_t(unsigned int, len, PAGE_SIZE - off); in map_data_for_request()
449 BUG_ON(ref == -ENOSPC); in map_data_for_request()
452 info->dev->otherend_id, in map_data_for_request()
454 shadow->gref[ref_cnt] = ref; in map_data_for_request()
455 shadow->seg[ref_cnt].gref = ref; in map_data_for_request()
456 shadow->seg[ref_cnt].offset = (uint16_t)off; in map_data_for_request()
457 shadow->seg[ref_cnt].length = (uint16_t)bytes; in map_data_for_request()
460 len -= bytes; in map_data_for_request()
470 off = sg->offset; in map_data_for_request()
471 len = sg->length; in map_data_for_request()
479 bytes = min_t(unsigned int, len, PAGE_SIZE - off); in map_data_for_request()
483 BUG_ON(ref == -ENOSPC); in map_data_for_request()
486 info->dev->otherend_id, in map_data_for_request()
490 shadow->gref[ref_cnt] = ref; in map_data_for_request()
491 seg->gref = ref; in map_data_for_request()
492 seg->offset = (uint16_t)off; in map_data_for_request()
493 seg->length = (uint16_t)bytes; in map_data_for_request()
497 len -= bytes; in map_data_for_request()
498 data_len -= bytes; in map_data_for_request()
505 shadow->nr_segments = VSCSIIF_SG_GRANT | seg_grants; in map_data_for_request()
507 shadow->nr_segments = (uint8_t)ref_cnt; in map_data_for_request()
508 shadow->nr_grants = ref_cnt; in map_data_for_request()
515 if (info->pause) in scsifront_enter()
517 info->callers++; in scsifront_enter()
523 info->callers--; in scsifront_return()
524 if (info->callers) in scsifront_return()
527 if (!info->waiting_pause) in scsifront_return()
530 info->waiting_pause = 0; in scsifront_return()
531 wake_up(&info->wq_pause); in scsifront_return()
542 sc->result = 0; in scsifront_queuecommand()
544 shadow->sc = sc; in scsifront_queuecommand()
545 shadow->act = VSCSIIF_ACT_SCSI_CDB; in scsifront_queuecommand()
547 spin_lock_irqsave(shost->host_lock, flags); in scsifront_queuecommand()
549 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
557 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
558 if (err == -ENOMEM) in scsifront_queuecommand()
560 sc->result = DID_ERROR << 16; in scsifront_queuecommand()
561 sc->scsi_done(sc); in scsifront_queuecommand()
571 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
577 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
589 struct Scsi_Host *host = sc->device->host; in scsifront_action_handler() local
590 struct vscsifrnt_info *info = shost_priv(host); in scsifront_action_handler()
598 shadow->act = act; in scsifront_action_handler()
599 shadow->rslt_reset = RSLT_RESET_WAITING; in scsifront_action_handler()
600 shadow->sc = sc; in scsifront_action_handler()
601 shadow->ref_rqid = s->rqid; in scsifront_action_handler()
602 init_waitqueue_head(&shadow->wq_reset); in scsifront_action_handler()
604 spin_lock_irq(host->host_lock); in scsifront_action_handler()
616 info->wait_ring_available = 1; in scsifront_action_handler()
617 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
618 err = wait_event_interruptible(info->wq_sync, in scsifront_action_handler()
619 !info->wait_ring_available); in scsifront_action_handler()
620 spin_lock_irq(host->host_lock); in scsifront_action_handler()
623 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
624 err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset); in scsifront_action_handler()
625 spin_lock_irq(host->host_lock); in scsifront_action_handler()
628 err = shadow->rslt_reset; in scsifront_action_handler()
629 scsifront_put_rqid(info, shadow->rqid); in scsifront_action_handler()
632 spin_lock(&info->shadow_lock); in scsifront_action_handler()
633 shadow->rslt_reset = RSLT_RESET_ERR; in scsifront_action_handler()
634 spin_unlock(&info->shadow_lock); in scsifront_action_handler()
639 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
643 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
662 struct vscsifrnt_info *info = shost_priv(sdev->host); in scsifront_sdev_configure()
665 if (info && current == info->curr) { in scsifront_sdev_configure()
666 err = xenbus_printf(XBT_NIL, info->dev->nodename, in scsifront_sdev_configure()
667 info->dev_state_path, "%d", XenbusStateConnected); in scsifront_sdev_configure()
669 xenbus_dev_error(info->dev, err, in scsifront_sdev_configure()
680 struct vscsifrnt_info *info = shost_priv(sdev->host); in scsifront_sdev_destroy()
683 if (info && current == info->curr) { in scsifront_sdev_destroy()
684 err = xenbus_printf(XBT_NIL, info->dev->nodename, in scsifront_sdev_destroy()
685 info->dev_state_path, "%d", XenbusStateClosed); in scsifront_sdev_destroy()
687 xenbus_dev_error(info->dev, err, in scsifront_sdev_destroy()
702 .this_id = -1,
710 struct xenbus_device *dev = info->dev; in scsifront_alloc_ring()
713 int err = -ENOMEM; in scsifront_alloc_ring()
723 FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); in scsifront_alloc_ring()
732 info->ring_ref = gref; in scsifront_alloc_ring()
734 err = xenbus_alloc_evtchn(dev, &info->evtchn); in scsifront_alloc_ring()
740 err = bind_evtchn_to_irq(info->evtchn); in scsifront_alloc_ring()
746 info->irq = err; in scsifront_alloc_ring()
748 err = request_threaded_irq(info->irq, NULL, scsifront_irq_fn, in scsifront_alloc_ring()
759 unbind_from_irqhandler(info->irq, info); in scsifront_alloc_ring()
761 gnttab_end_foreign_access(info->ring_ref, 0, in scsifront_alloc_ring()
762 (unsigned long)info->ring.sring); in scsifront_alloc_ring()
769 unbind_from_irqhandler(info->irq, info); in scsifront_free_ring()
770 gnttab_end_foreign_access(info->ring_ref, 0, in scsifront_free_ring()
771 (unsigned long)info->ring.sring); in scsifront_free_ring()
776 struct xenbus_device *dev = info->dev; in scsifront_init_ring()
785 pr_debug("%s: %u %u\n", __func__, info->ring_ref, info->evtchn); in scsifront_init_ring()
792 err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u", in scsifront_init_ring()
793 info->ring_ref); in scsifront_init_ring()
795 xenbus_dev_fatal(dev, err, "%s", "writing ring-ref"); in scsifront_init_ring()
799 err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", in scsifront_init_ring()
800 info->evtchn); in scsifront_init_ring()
803 xenbus_dev_fatal(dev, err, "%s", "writing event-channel"); in scsifront_init_ring()
809 if (err == -EAGAIN) in scsifront_init_ring()
827 const struct xenbus_device_id *id) in scsifront_probe() argument
830 struct Scsi_Host *host; in scsifront_probe() local
831 int err = -ENOMEM; in scsifront_probe()
834 host = scsi_host_alloc(&scsifront_sht, sizeof(*info)); in scsifront_probe()
835 if (!host) { in scsifront_probe()
836 xenbus_dev_fatal(dev, err, "fail to allocate scsi host"); in scsifront_probe()
839 info = (struct vscsifrnt_info *)host->hostdata; in scsifront_probe()
841 dev_set_drvdata(&dev->dev, info); in scsifront_probe()
842 info->dev = dev; in scsifront_probe()
844 bitmap_fill(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in scsifront_probe()
848 scsi_host_put(host); in scsifront_probe()
852 init_waitqueue_head(&info->wq_sync); in scsifront_probe()
853 init_waitqueue_head(&info->wq_pause); in scsifront_probe()
854 spin_lock_init(&info->shadow_lock); in scsifront_probe()
856 snprintf(name, TASK_COMM_LEN, "vscsiif.%d", host->host_no); in scsifront_probe()
858 host->max_id = VSCSIIF_MAX_TARGET; in scsifront_probe()
859 host->max_channel = 0; in scsifront_probe()
860 host->max_lun = VSCSIIF_MAX_LUN; in scsifront_probe()
861 host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512; in scsifront_probe()
862 host->max_cmd_len = VSCSIIF_MAX_COMMAND_SIZE; in scsifront_probe()
864 err = scsi_add_host(host, &dev->dev); in scsifront_probe()
866 dev_err(&dev->dev, "fail to add scsi host %d\n", err); in scsifront_probe()
869 info->host = host; in scsifront_probe()
870 info->host_active = 1; in scsifront_probe()
878 scsi_host_put(host); in scsifront_probe()
884 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_resume()
885 struct Scsi_Host *host = info->host; in scsifront_resume() local
888 spin_lock_irq(host->host_lock); in scsifront_resume()
893 spin_unlock_irq(host->host_lock); in scsifront_resume()
899 dev_err(&dev->dev, "fail to resume %d\n", err); in scsifront_resume()
900 scsi_host_put(host); in scsifront_resume()
911 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_suspend()
912 struct Scsi_Host *host = info->host; in scsifront_suspend() local
916 spin_lock_irq(host->host_lock); in scsifront_suspend()
917 info->pause = 1; in scsifront_suspend()
918 while (info->callers && !err) { in scsifront_suspend()
919 info->waiting_pause = 1; in scsifront_suspend()
920 info->wait_ring_available = 0; in scsifront_suspend()
921 spin_unlock_irq(host->host_lock); in scsifront_suspend()
922 wake_up(&info->wq_sync); in scsifront_suspend()
923 err = wait_event_interruptible(info->wq_pause, in scsifront_suspend()
924 !info->waiting_pause); in scsifront_suspend()
925 spin_lock_irq(host->host_lock); in scsifront_suspend()
927 spin_unlock_irq(host->host_lock); in scsifront_suspend()
933 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_remove()
935 pr_debug("%s: %s removed\n", __func__, dev->nodename); in scsifront_remove()
938 if (info->host_active) { in scsifront_remove()
940 scsi_remove_host(info->host); in scsifront_remove()
941 info->host_active = 0; in scsifront_remove()
946 scsi_host_put(info->host); in scsifront_remove()
953 struct xenbus_device *dev = info->dev; in scsifront_disconnect()
954 struct Scsi_Host *host = info->host; in scsifront_disconnect() local
956 pr_debug("%s: %s disconnect\n", __func__, dev->nodename); in scsifront_disconnect()
965 if (info->host_active) { in scsifront_disconnect()
966 scsi_remove_host(host); in scsifront_disconnect()
967 info->host_active = 0; in scsifront_disconnect()
976 struct xenbus_device *dev = info->dev; in scsifront_do_lun_hotplug()
985 dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n); in scsifront_do_lun_hotplug()
990 BUG_ON(info->curr); in scsifront_do_lun_hotplug()
991 info->curr = current; in scsifront_do_lun_hotplug()
995 snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]); in scsifront_do_lun_hotplug()
996 err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u", in scsifront_do_lun_hotplug()
1002 snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]); in scsifront_do_lun_hotplug()
1003 err = xenbus_scanf(XBT_NIL, dev->otherend, str, in scsifront_do_lun_hotplug()
1013 snprintf(info->dev_state_path, sizeof(info->dev_state_path), in scsifront_do_lun_hotplug()
1014 "vscsi-devs/%s/state", dir[i]); in scsifront_do_lun_hotplug()
1021 if (scsi_add_device(info->host, chn, tgt, lun)) { in scsifront_do_lun_hotplug()
1022 dev_err(&dev->dev, "scsi_add_device\n"); in scsifront_do_lun_hotplug()
1023 err = xenbus_printf(XBT_NIL, dev->nodename, in scsifront_do_lun_hotplug()
1024 info->dev_state_path, in scsifront_do_lun_hotplug()
1035 sdev = scsi_device_lookup(info->host, chn, tgt, lun); in scsifront_do_lun_hotplug()
1043 err = xenbus_printf(XBT_NIL, dev->nodename, in scsifront_do_lun_hotplug()
1044 info->dev_state_path, in scsifront_do_lun_hotplug()
1056 info->curr = NULL; in scsifront_do_lun_hotplug()
1065 struct Scsi_Host *host = info->host; in scsifront_read_backend_params() local
1067 sg_grant = xenbus_read_unsigned(dev->otherend, "feature-sg-grant", 0); in scsifront_read_backend_params()
1074 if (!info->pause && sg_grant) in scsifront_read_backend_params()
1075 dev_info(&dev->dev, "using up to %d SG entries\n", nr_segs); in scsifront_read_backend_params()
1076 else if (info->pause && nr_segs < host->sg_tablesize) in scsifront_read_backend_params()
1077 dev_warn(&dev->dev, in scsifront_read_backend_params()
1078 "SG entries decreased from %d to %u - device may not work properly anymore\n", in scsifront_read_backend_params()
1079 host->sg_tablesize, nr_segs); in scsifront_read_backend_params()
1081 host->sg_tablesize = nr_segs; in scsifront_read_backend_params()
1082 host->max_sectors = (nr_segs - 1) * PAGE_SIZE / 512; in scsifront_read_backend_params()
1088 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_backend_changed()
1090 pr_debug("%s: %p %u %u\n", __func__, dev, dev->state, backend_state); in scsifront_backend_changed()
1102 if (info->pause) { in scsifront_backend_changed()
1105 info->pause = 0; in scsifront_backend_changed()
1109 if (xenbus_read_driver_state(dev->nodename) == in scsifront_backend_changed()
1113 if (dev->state != XenbusStateConnected) in scsifront_backend_changed()
1118 if (dev->state == XenbusStateClosed) in scsifront_backend_changed()
1154 return -ENODEV; in scsifront_init()