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

95 #define RSLT_RESET_ERR		-1
105 struct Scsi_Host *host; member
123 /* Following items are protected by the host lock. */
139 info->wait_ring_available = 0; in scsifront_wake_up()
140 wake_up(&info->wq_sync); in scsifront_wake_up()
148 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_get_rqid()
150 free = find_first_bit(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in scsifront_get_rqid()
151 __clear_bit(free, info->shadow_free_bitmap); in scsifront_get_rqid()
153 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_get_rqid()
158 static int _scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id) in _scsifront_put_rqid() argument
160 int empty = bitmap_empty(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in _scsifront_put_rqid()
162 __set_bit(id, info->shadow_free_bitmap); in _scsifront_put_rqid()
163 info->shadow[id] = NULL; in _scsifront_put_rqid()
165 return empty || info->wait_ring_available; in _scsifront_put_rqid()
168 static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id) in scsifront_put_rqid() argument
173 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_put_rqid()
174 kick = _scsifront_put_rqid(info, id); in scsifront_put_rqid()
175 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_put_rqid()
184 struct vscsiif_front_ring *ring = &(info->ring); in scsifront_do_request()
186 struct scsi_cmnd *sc = shadow->sc; in scsifront_do_request()
187 uint32_t id; in scsifront_do_request() local
190 if (RING_FULL(&info->ring)) in scsifront_do_request()
191 return -EBUSY; in scsifront_do_request()
193 id = scsifront_get_rqid(info); /* use id in response */ in scsifront_do_request()
194 if (id >= VSCSIIF_MAX_REQS) in scsifront_do_request()
195 return -EBUSY; in scsifront_do_request()
197 info->shadow[id] = shadow; in scsifront_do_request()
198 shadow->rqid = id; in scsifront_do_request()
200 ring_req = RING_GET_REQUEST(&(info->ring), ring->req_prod_pvt); in scsifront_do_request()
201 ring->req_prod_pvt++; in scsifront_do_request()
203 ring_req->rqid = id; in scsifront_do_request()
204 ring_req->act = shadow->act; in scsifront_do_request()
205 ring_req->ref_rqid = shadow->ref_rqid; in scsifront_do_request()
206 ring_req->nr_segments = shadow->nr_segments; in scsifront_do_request()
208 ring_req->id = sc->device->id; in scsifront_do_request()
209 ring_req->lun = sc->device->lun; in scsifront_do_request()
210 ring_req->channel = sc->device->channel; in scsifront_do_request()
211 ring_req->cmd_len = sc->cmd_len; in scsifront_do_request()
213 BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE); in scsifront_do_request()
215 memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len); in scsifront_do_request()
217 ring_req->sc_data_direction = (uint8_t)sc->sc_data_direction; in scsifront_do_request()
218 ring_req->timeout_per_command = scsi_cmd_to_rq(sc)->timeout / HZ; in scsifront_do_request()
220 for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++) in scsifront_do_request()
221 ring_req->seg[i] = shadow->seg[i]; in scsifront_do_request()
223 shadow->inflight = true; in scsifront_do_request()
227 notify_remote_via_irq(info->irq); in scsifront_do_request()
234 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME "%s\n" in scsifront_set_error()
236 info->host_active = STATE_ERROR; in scsifront_set_error()
244 if (shadow->sc->sc_data_direction == DMA_NONE) in scsifront_gnttab_done()
247 for (i = 0; i < shadow->nr_grants; i++) { in scsifront_gnttab_done()
248 if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) { in scsifront_gnttab_done()
254 kfree(shadow->sg); in scsifront_gnttab_done()
304 uint32_t id; in scsifront_cdb_cmd_done() local
307 id = ring_rsp->rqid; in scsifront_cdb_cmd_done()
308 shadow = info->shadow[id]; in scsifront_cdb_cmd_done()
309 sc = shadow->sc; in scsifront_cdb_cmd_done()
314 if (info->host_active == STATE_ERROR) in scsifront_cdb_cmd_done()
316 scsifront_put_rqid(info, id); in scsifront_cdb_cmd_done()
318 set_host_byte(sc, scsifront_host_byte(ring_rsp->rslt)); in scsifront_cdb_cmd_done()
319 set_status_byte(sc, XEN_VSCSIIF_RSLT_STATUS(ring_rsp->rslt)); in scsifront_cdb_cmd_done()
320 scsi_set_resid(sc, ring_rsp->residual_len); in scsifront_cdb_cmd_done()
323 ring_rsp->sense_len); in scsifront_cdb_cmd_done()
326 memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len); in scsifront_cdb_cmd_done()
334 uint16_t id = ring_rsp->rqid; in scsifront_sync_cmd_done() local
336 struct vscsifrnt_shadow *shadow = info->shadow[id]; in scsifront_sync_cmd_done()
339 spin_lock_irqsave(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
340 shadow->wait_reset = 1; in scsifront_sync_cmd_done()
341 switch (shadow->rslt_reset) { in scsifront_sync_cmd_done()
343 if (ring_rsp->rslt == XEN_VSCSIIF_RSLT_RESET_SUCCESS) in scsifront_sync_cmd_done()
344 shadow->rslt_reset = SUCCESS; in scsifront_sync_cmd_done()
346 shadow->rslt_reset = FAILED; in scsifront_sync_cmd_done()
349 kick = _scsifront_put_rqid(info, id); in scsifront_sync_cmd_done()
350 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
359 spin_unlock_irqrestore(&info->shadow_lock, flags); in scsifront_sync_cmd_done()
361 wake_up(&shadow->wq_reset); in scsifront_sync_cmd_done()
369 if (ring_rsp->rqid >= VSCSIIF_MAX_REQS || in scsifront_do_response()
370 !info->shadow[ring_rsp->rqid]->inflight) { in scsifront_do_response()
374 shadow = info->shadow[ring_rsp->rqid]; in scsifront_do_response()
375 shadow->inflight = false; in scsifront_do_response()
377 if (shadow->act == VSCSIIF_ACT_SCSI_CDB) in scsifront_do_response()
390 rp = READ_ONCE(info->ring.sring->rsp_prod); in scsifront_ring_drain()
392 if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) { in scsifront_ring_drain()
396 for (i = info->ring.rsp_cons; i != rp; i++) { in scsifront_ring_drain()
397 RING_COPY_RESPONSE(&info->ring, i, &ring_rsp); in scsifront_ring_drain()
399 if (info->host_active == STATE_ERROR) in scsifront_ring_drain()
404 info->ring.rsp_cons = i; in scsifront_ring_drain()
406 if (i != info->ring.req_prod_pvt) in scsifront_ring_drain()
407 RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do); in scsifront_ring_drain()
409 info->ring.sring->rsp_event = i + 1; in scsifront_ring_drain()
420 spin_lock_irqsave(info->host->host_lock, flags); in scsifront_cmd_done()
424 info->wait_ring_available = 0; in scsifront_cmd_done()
426 spin_unlock_irqrestore(info->host->host_lock, flags); in scsifront_cmd_done()
428 wake_up(&info->wq_sync); in scsifront_cmd_done()
438 if (info->host_active == STATE_ERROR) { in scsifront_irq_fn()
460 if (test_bit(i, info->shadow_free_bitmap)) in scsifront_finish_all()
477 int grant_ro = (sc->sc_data_direction == DMA_TO_DEVICE); in map_data_for_request()
484 if (sc->sc_data_direction == DMA_NONE || !data_len) in map_data_for_request()
488 data_grants += PFN_UP(sg->offset + sg->length); in map_data_for_request()
491 if (data_grants > info->host->sg_tablesize) { in map_data_for_request()
492 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME in map_data_for_request()
494 return -E2BIG; in map_data_for_request()
497 shadow->sg = kcalloc(data_grants, in map_data_for_request()
499 if (!shadow->sg) in map_data_for_request()
500 return -ENOMEM; in map_data_for_request()
502 seg = shadow->sg ? : shadow->seg; in map_data_for_request()
507 kfree(shadow->sg); in map_data_for_request()
508 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME in map_data_for_request()
510 return -ENOMEM; in map_data_for_request()
518 bytes = min_t(unsigned int, len, PAGE_SIZE - off); in map_data_for_request()
521 BUG_ON(ref == -ENOSPC); in map_data_for_request()
524 info->dev->otherend_id, in map_data_for_request()
526 shadow->gref[ref_cnt] = ref; in map_data_for_request()
527 shadow->seg[ref_cnt].gref = ref; in map_data_for_request()
528 shadow->seg[ref_cnt].offset = (uint16_t)off; in map_data_for_request()
529 shadow->seg[ref_cnt].length = (uint16_t)bytes; in map_data_for_request()
532 len -= bytes; in map_data_for_request()
542 off = sg->offset; in map_data_for_request()
543 len = sg->length; in map_data_for_request()
551 bytes = min_t(unsigned int, len, PAGE_SIZE - off); in map_data_for_request()
555 BUG_ON(ref == -ENOSPC); in map_data_for_request()
558 info->dev->otherend_id, in map_data_for_request()
562 shadow->gref[ref_cnt] = ref; in map_data_for_request()
563 seg->gref = ref; in map_data_for_request()
564 seg->offset = (uint16_t)off; in map_data_for_request()
565 seg->length = (uint16_t)bytes; in map_data_for_request()
569 len -= bytes; in map_data_for_request()
570 data_len -= bytes; in map_data_for_request()
577 shadow->nr_segments = VSCSIIF_SG_GRANT | seg_grants; in map_data_for_request()
579 shadow->nr_segments = (uint8_t)ref_cnt; in map_data_for_request()
580 shadow->nr_grants = ref_cnt; in map_data_for_request()
587 if (info->pause) in scsifront_enter()
589 info->callers++; in scsifront_enter()
595 info->callers--; in scsifront_return()
596 if (info->callers) in scsifront_return()
599 if (!info->waiting_pause) in scsifront_return()
602 info->waiting_pause = 0; in scsifront_return()
603 wake_up(&info->wq_pause); in scsifront_return()
614 if (info->host_active == STATE_ERROR) in scsifront_queuecommand()
617 sc->result = 0; in scsifront_queuecommand()
619 shadow->sc = sc; in scsifront_queuecommand()
620 shadow->act = VSCSIIF_ACT_SCSI_CDB; in scsifront_queuecommand()
622 spin_lock_irqsave(shost->host_lock, flags); in scsifront_queuecommand()
624 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
632 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
633 if (err == -ENOMEM) in scsifront_queuecommand()
635 sc->result = DID_ERROR << 16; in scsifront_queuecommand()
646 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
652 spin_unlock_irqrestore(shost->host_lock, flags); in scsifront_queuecommand()
664 struct Scsi_Host *host = sc->device->host; in scsifront_action_handler() local
665 struct vscsifrnt_info *info = shost_priv(host); in scsifront_action_handler()
669 if (info->host_active == STATE_ERROR) in scsifront_action_handler()
676 shadow->act = act; in scsifront_action_handler()
677 shadow->rslt_reset = RSLT_RESET_WAITING; in scsifront_action_handler()
678 shadow->sc = sc; in scsifront_action_handler()
679 shadow->ref_rqid = s->rqid; in scsifront_action_handler()
680 init_waitqueue_head(&shadow->wq_reset); in scsifront_action_handler()
682 spin_lock_irq(host->host_lock); in scsifront_action_handler()
694 info->wait_ring_available = 1; in scsifront_action_handler()
695 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
696 err = wait_event_interruptible(info->wq_sync, in scsifront_action_handler()
697 !info->wait_ring_available); in scsifront_action_handler()
698 spin_lock_irq(host->host_lock); in scsifront_action_handler()
701 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
702 err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset); in scsifront_action_handler()
703 spin_lock_irq(host->host_lock); in scsifront_action_handler()
706 err = shadow->rslt_reset; in scsifront_action_handler()
707 scsifront_put_rqid(info, shadow->rqid); in scsifront_action_handler()
710 spin_lock(&info->shadow_lock); in scsifront_action_handler()
711 shadow->rslt_reset = RSLT_RESET_ERR; in scsifront_action_handler()
712 spin_unlock(&info->shadow_lock); in scsifront_action_handler()
717 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
721 spin_unlock_irq(host->host_lock); in scsifront_action_handler()
740 struct vscsifrnt_info *info = shost_priv(sdev->host); in scsifront_sdev_configure()
743 if (info->host_active == STATE_ERROR) in scsifront_sdev_configure()
744 return -EIO; in scsifront_sdev_configure()
746 if (current == info->curr) { in scsifront_sdev_configure()
747 err = xenbus_printf(XBT_NIL, info->dev->nodename, in scsifront_sdev_configure()
748 info->dev_state_path, "%d", XenbusStateConnected); in scsifront_sdev_configure()
750 xenbus_dev_error(info->dev, err, in scsifront_sdev_configure()
761 struct vscsifrnt_info *info = shost_priv(sdev->host); in scsifront_sdev_destroy()
764 if (current == info->curr) { in scsifront_sdev_destroy()
765 err = xenbus_printf(XBT_NIL, info->dev->nodename, in scsifront_sdev_destroy()
766 info->dev_state_path, "%d", XenbusStateClosed); in scsifront_sdev_destroy()
768 xenbus_dev_error(info->dev, err, in scsifront_sdev_destroy()
783 .this_id = -1,
791 struct xenbus_device *dev = info->dev; in scsifront_alloc_ring()
797 &info->ring_ref); in scsifront_alloc_ring()
801 XEN_FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); in scsifront_alloc_ring()
803 err = xenbus_alloc_evtchn(dev, &info->evtchn); in scsifront_alloc_ring()
809 err = bind_evtchn_to_irq_lateeoi(info->evtchn); in scsifront_alloc_ring()
815 info->irq = err; in scsifront_alloc_ring()
817 err = request_threaded_irq(info->irq, NULL, scsifront_irq_fn, in scsifront_alloc_ring()
828 unbind_from_irqhandler(info->irq, info); in scsifront_alloc_ring()
830 xenbus_teardown_ring((void **)&sring, 1, &info->ring_ref); in scsifront_alloc_ring()
837 unbind_from_irqhandler(info->irq, info); in scsifront_free_ring()
838 xenbus_teardown_ring((void **)&info->ring.sring, 1, &info->ring_ref); in scsifront_free_ring()
843 struct xenbus_device *dev = info->dev; in scsifront_init_ring()
852 pr_debug("%s: %u %u\n", __func__, info->ring_ref, info->evtchn); in scsifront_init_ring()
859 err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u", in scsifront_init_ring()
860 info->ring_ref); in scsifront_init_ring()
862 xenbus_dev_fatal(dev, err, "%s", "writing ring-ref"); in scsifront_init_ring()
866 err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", in scsifront_init_ring()
867 info->evtchn); in scsifront_init_ring()
870 xenbus_dev_fatal(dev, err, "%s", "writing event-channel"); in scsifront_init_ring()
876 if (err == -EAGAIN) in scsifront_init_ring()
894 const struct xenbus_device_id *id) in scsifront_probe() argument
897 struct Scsi_Host *host; in scsifront_probe() local
898 int err = -ENOMEM; in scsifront_probe()
901 host = scsi_host_alloc(&scsifront_sht, sizeof(*info)); in scsifront_probe()
902 if (!host) { in scsifront_probe()
903 xenbus_dev_fatal(dev, err, "fail to allocate scsi host"); in scsifront_probe()
906 info = shost_priv(host); in scsifront_probe()
908 dev_set_drvdata(&dev->dev, info); in scsifront_probe()
909 info->dev = dev; in scsifront_probe()
911 bitmap_fill(info->shadow_free_bitmap, VSCSIIF_MAX_REQS); in scsifront_probe()
915 scsi_host_put(host); in scsifront_probe()
919 init_waitqueue_head(&info->wq_sync); in scsifront_probe()
920 init_waitqueue_head(&info->wq_pause); in scsifront_probe()
921 spin_lock_init(&info->shadow_lock); in scsifront_probe()
923 snprintf(name, TASK_COMM_LEN, "vscsiif.%d", host->host_no); in scsifront_probe()
925 host->max_id = VSCSIIF_MAX_TARGET; in scsifront_probe()
926 host->max_channel = 0; in scsifront_probe()
927 host->max_lun = VSCSIIF_MAX_LUN; in scsifront_probe()
928 host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512; in scsifront_probe()
929 host->max_cmd_len = VSCSIIF_MAX_COMMAND_SIZE; in scsifront_probe()
931 err = scsi_add_host(host, &dev->dev); in scsifront_probe()
933 dev_err(&dev->dev, "fail to add scsi host %d\n", err); in scsifront_probe()
936 info->host = host; in scsifront_probe()
937 info->host_active = STATE_ACTIVE; in scsifront_probe()
945 scsi_host_put(host); in scsifront_probe()
951 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_resume()
952 struct Scsi_Host *host = info->host; in scsifront_resume() local
955 spin_lock_irq(host->host_lock); in scsifront_resume()
960 spin_unlock_irq(host->host_lock); in scsifront_resume()
966 dev_err(&dev->dev, "fail to resume %d\n", err); in scsifront_resume()
967 scsi_host_put(host); in scsifront_resume()
978 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_suspend()
979 struct Scsi_Host *host = info->host; in scsifront_suspend() local
983 spin_lock_irq(host->host_lock); in scsifront_suspend()
984 info->pause = 1; in scsifront_suspend()
985 while (info->callers && !err) { in scsifront_suspend()
986 info->waiting_pause = 1; in scsifront_suspend()
987 info->wait_ring_available = 0; in scsifront_suspend()
988 spin_unlock_irq(host->host_lock); in scsifront_suspend()
989 wake_up(&info->wq_sync); in scsifront_suspend()
990 err = wait_event_interruptible(info->wq_pause, in scsifront_suspend()
991 !info->waiting_pause); in scsifront_suspend()
992 spin_lock_irq(host->host_lock); in scsifront_suspend()
994 spin_unlock_irq(host->host_lock); in scsifront_suspend()
1000 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_remove()
1002 pr_debug("%s: %s removed\n", __func__, dev->nodename); in scsifront_remove()
1005 if (info->host_active != STATE_INACTIVE) { in scsifront_remove()
1007 scsi_remove_host(info->host); in scsifront_remove()
1008 info->host_active = STATE_INACTIVE; in scsifront_remove()
1013 scsi_host_put(info->host); in scsifront_remove()
1018 struct xenbus_device *dev = info->dev; in scsifront_disconnect()
1019 struct Scsi_Host *host = info->host; in scsifront_disconnect() local
1021 pr_debug("%s: %s disconnect\n", __func__, dev->nodename); in scsifront_disconnect()
1030 if (info->host_active != STATE_INACTIVE) { in scsifront_disconnect()
1031 scsi_remove_host(host); in scsifront_disconnect()
1032 info->host_active = STATE_INACTIVE; in scsifront_disconnect()
1041 struct xenbus_device *dev = info->dev; in scsifront_do_lun_hotplug()
1050 if (info->host_active == STATE_ERROR) in scsifront_do_lun_hotplug()
1053 dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n); in scsifront_do_lun_hotplug()
1058 BUG_ON(info->curr); in scsifront_do_lun_hotplug()
1059 info->curr = current; in scsifront_do_lun_hotplug()
1063 snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]); in scsifront_do_lun_hotplug()
1064 err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u", in scsifront_do_lun_hotplug()
1070 snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]); in scsifront_do_lun_hotplug()
1071 err = xenbus_scanf(XBT_NIL, dev->otherend, str, in scsifront_do_lun_hotplug()
1081 snprintf(info->dev_state_path, sizeof(info->dev_state_path), in scsifront_do_lun_hotplug()
1082 "vscsi-devs/%s/state", dir[i]); in scsifront_do_lun_hotplug()
1089 if (scsi_add_device(info->host, chn, tgt, lun)) { in scsifront_do_lun_hotplug()
1090 dev_err(&dev->dev, "scsi_add_device\n"); in scsifront_do_lun_hotplug()
1091 err = xenbus_printf(XBT_NIL, dev->nodename, in scsifront_do_lun_hotplug()
1092 info->dev_state_path, in scsifront_do_lun_hotplug()
1103 sdev = scsi_device_lookup(info->host, chn, tgt, lun); in scsifront_do_lun_hotplug()
1111 err = xenbus_printf(XBT_NIL, dev->nodename, in scsifront_do_lun_hotplug()
1112 info->dev_state_path, in scsifront_do_lun_hotplug()
1124 info->curr = NULL; in scsifront_do_lun_hotplug()
1133 struct Scsi_Host *host = info->host; in scsifront_read_backend_params() local
1135 sg_grant = xenbus_read_unsigned(dev->otherend, "feature-sg-grant", 0); in scsifront_read_backend_params()
1142 if (!info->pause && sg_grant) in scsifront_read_backend_params()
1143 dev_info(&dev->dev, "using up to %d SG entries\n", nr_segs); in scsifront_read_backend_params()
1144 else if (info->pause && nr_segs < host->sg_tablesize) in scsifront_read_backend_params()
1145 dev_warn(&dev->dev, in scsifront_read_backend_params()
1146 "SG entries decreased from %d to %u - device may not work properly anymore\n", in scsifront_read_backend_params()
1147 host->sg_tablesize, nr_segs); in scsifront_read_backend_params()
1149 host->sg_tablesize = nr_segs; in scsifront_read_backend_params()
1150 host->max_sectors = (nr_segs - 1) * PAGE_SIZE / 512; in scsifront_read_backend_params()
1156 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev); in scsifront_backend_changed()
1158 pr_debug("%s: %p %u %u\n", __func__, dev, dev->state, backend_state); in scsifront_backend_changed()
1170 if (info->pause) { in scsifront_backend_changed()
1173 info->pause = 0; in scsifront_backend_changed()
1177 if (xenbus_read_driver_state(dev->nodename) == in scsifront_backend_changed()
1181 if (dev->state != XenbusStateConnected) in scsifront_backend_changed()
1186 if (dev->state == XenbusStateClosed) in scsifront_backend_changed()
1222 return -ENODEV; in scsifront_init()