brintos

brintos / linux-shallow public Read only

0
0
Text · 30.4 KiB · 9ec55dd Raw
1238 lines · c
1/*2 * Xen SCSI frontend driver3 *4 * Copyright (c) 2008, FUJITSU Limited5 *6 * This program is free software; you can redistribute it and/or7 * modify it under the terms of the GNU General Public License version 28 * as published by the Free Software Foundation; or, when distributed9 * separately from the Linux kernel or incorporated into other10 * software packages, subject to the following license:11 *12 * Permission is hereby granted, free of charge, to any person obtaining a copy13 * of this source file (the "Software"), to deal in the Software without14 * restriction, including without limitation the rights to use, copy, modify,15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,16 * and to permit persons to whom the Software is furnished to do so, subject to17 * the following conditions:18 *19 * The above copyright notice and this permission notice shall be included in20 * all copies or substantial portions of the Software.21 *22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS28 * IN THE SOFTWARE.29 */30 31#include <linux/module.h>32#include <linux/kernel.h>33#include <linux/device.h>34#include <linux/wait.h>35#include <linux/interrupt.h>36#include <linux/mutex.h>37#include <linux/spinlock.h>38#include <linux/sched.h>39#include <linux/blkdev.h>40#include <linux/pfn.h>41#include <linux/slab.h>42#include <linux/bitops.h>43 44#include <scsi/scsi_cmnd.h>45#include <scsi/scsi_device.h>46#include <scsi/scsi.h>47#include <scsi/scsi_host.h>48 49#include <xen/xen.h>50#include <xen/xenbus.h>51#include <xen/grant_table.h>52#include <xen/events.h>53#include <xen/page.h>54 55#include <xen/interface/grant_table.h>56#include <xen/interface/io/vscsiif.h>57#include <xen/interface/io/protocols.h>58 59#include <asm/xen/hypervisor.h>60 61#define VSCSIFRONT_OP_ADD_LUN	162#define VSCSIFRONT_OP_DEL_LUN	263#define VSCSIFRONT_OP_READD_LUN	364 65/* Tuning point. */66#define VSCSIIF_DEFAULT_CMD_PER_LUN 1067#define VSCSIIF_MAX_TARGET          6468#define VSCSIIF_MAX_LUN             25569 70#define VSCSIIF_RING_SIZE	__CONST_RING_SIZE(vscsiif, PAGE_SIZE)71#define VSCSIIF_MAX_REQS	VSCSIIF_RING_SIZE72 73#define vscsiif_grants_sg(_sg)	(PFN_UP((_sg) *		\74				sizeof(struct scsiif_request_segment)))75 76struct vscsifrnt_shadow {77	/* command between backend and frontend */78	unsigned char act;79	uint8_t nr_segments;80	uint16_t rqid;81	uint16_t ref_rqid;82 83	bool inflight;84 85	unsigned int nr_grants;		/* number of grants in gref[] */86	struct scsiif_request_segment *sg;	/* scatter/gather elements */87	struct scsiif_request_segment seg[VSCSIIF_SG_TABLESIZE];88 89	/* Do reset or abort function. */90	wait_queue_head_t wq_reset;	/* reset work queue           */91	int wait_reset;			/* reset work queue condition */92	int32_t rslt_reset;		/* reset response status:     */93					/* SUCCESS or FAILED or:      */94#define RSLT_RESET_WAITING	095#define RSLT_RESET_ERR		-196 97	/* Requested struct scsi_cmnd is stored from kernel. */98	struct scsi_cmnd *sc;99	int gref[vscsiif_grants_sg(SG_ALL) + SG_ALL];100};101 102struct vscsifrnt_info {103	struct xenbus_device *dev;104 105	struct Scsi_Host *host;106	enum {107		STATE_INACTIVE,108		STATE_ACTIVE,109		STATE_ERROR110	}  host_active;111 112	unsigned int evtchn;113	unsigned int irq;114 115	grant_ref_t ring_ref;116	struct vscsiif_front_ring ring;117	struct vscsiif_response	ring_rsp;118 119	spinlock_t shadow_lock;120	DECLARE_BITMAP(shadow_free_bitmap, VSCSIIF_MAX_REQS);121	struct vscsifrnt_shadow *shadow[VSCSIIF_MAX_REQS];122 123	/* Following items are protected by the host lock. */124	wait_queue_head_t wq_sync;125	wait_queue_head_t wq_pause;126	unsigned int wait_ring_available:1;127	unsigned int waiting_pause:1;128	unsigned int pause:1;129	unsigned callers;130 131	char dev_state_path[64];132	struct task_struct *curr;133};134 135static DEFINE_MUTEX(scsifront_mutex);136 137static void scsifront_wake_up(struct vscsifrnt_info *info)138{139	info->wait_ring_available = 0;140	wake_up(&info->wq_sync);141}142 143static int scsifront_get_rqid(struct vscsifrnt_info *info)144{145	unsigned long flags;146	int free;147 148	spin_lock_irqsave(&info->shadow_lock, flags);149 150	free = find_first_bit(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);151	__clear_bit(free, info->shadow_free_bitmap);152 153	spin_unlock_irqrestore(&info->shadow_lock, flags);154 155	return free;156}157 158static int _scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)159{160	int empty = bitmap_empty(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);161 162	__set_bit(id, info->shadow_free_bitmap);163	info->shadow[id] = NULL;164 165	return empty || info->wait_ring_available;166}167 168static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)169{170	unsigned long flags;171	int kick;172 173	spin_lock_irqsave(&info->shadow_lock, flags);174	kick = _scsifront_put_rqid(info, id);175	spin_unlock_irqrestore(&info->shadow_lock, flags);176 177	if (kick)178		scsifront_wake_up(info);179}180 181static int scsifront_do_request(struct vscsifrnt_info *info,182				struct vscsifrnt_shadow *shadow)183{184	struct vscsiif_front_ring *ring = &(info->ring);185	struct vscsiif_request *ring_req;186	struct scsi_cmnd *sc = shadow->sc;187	uint32_t id;188	int i, notify;189 190	if (RING_FULL(&info->ring))191		return -EBUSY;192 193	id = scsifront_get_rqid(info);	/* use id in response */194	if (id >= VSCSIIF_MAX_REQS)195		return -EBUSY;196 197	info->shadow[id] = shadow;198	shadow->rqid = id;199 200	ring_req = RING_GET_REQUEST(&(info->ring), ring->req_prod_pvt);201	ring->req_prod_pvt++;202 203	ring_req->rqid        = id;204	ring_req->act         = shadow->act;205	ring_req->ref_rqid    = shadow->ref_rqid;206	ring_req->nr_segments = shadow->nr_segments;207 208	ring_req->id      = sc->device->id;209	ring_req->lun     = sc->device->lun;210	ring_req->channel = sc->device->channel;211	ring_req->cmd_len = sc->cmd_len;212 213	BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE);214 215	memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len);216 217	ring_req->sc_data_direction   = (uint8_t)sc->sc_data_direction;218	ring_req->timeout_per_command = scsi_cmd_to_rq(sc)->timeout / HZ;219 220	for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++)221		ring_req->seg[i] = shadow->seg[i];222 223	shadow->inflight = true;224 225	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(ring, notify);226	if (notify)227		notify_remote_via_irq(info->irq);228 229	return 0;230}231 232static void scsifront_set_error(struct vscsifrnt_info *info, const char *msg)233{234	shost_printk(KERN_ERR, info->host, KBUILD_MODNAME "%s\n"235		     "Disabling device for further use\n", msg);236	info->host_active = STATE_ERROR;237}238 239static void scsifront_gnttab_done(struct vscsifrnt_info *info,240				  struct vscsifrnt_shadow *shadow)241{242	int i;243 244	if (shadow->sc->sc_data_direction == DMA_NONE)245		return;246 247	for (i = 0; i < shadow->nr_grants; i++) {248		if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) {249			scsifront_set_error(info, "grant still in use by backend");250			return;251		}252	}253 254	kfree(shadow->sg);255}256 257static unsigned int scsifront_host_byte(int32_t rslt)258{259	switch (XEN_VSCSIIF_RSLT_HOST(rslt)) {260	case XEN_VSCSIIF_RSLT_HOST_OK:261		return DID_OK;262	case XEN_VSCSIIF_RSLT_HOST_NO_CONNECT:263		return DID_NO_CONNECT;264	case XEN_VSCSIIF_RSLT_HOST_BUS_BUSY:265		return DID_BUS_BUSY;266	case XEN_VSCSIIF_RSLT_HOST_TIME_OUT:267		return DID_TIME_OUT;268	case XEN_VSCSIIF_RSLT_HOST_BAD_TARGET:269		return DID_BAD_TARGET;270	case XEN_VSCSIIF_RSLT_HOST_ABORT:271		return DID_ABORT;272	case XEN_VSCSIIF_RSLT_HOST_PARITY:273		return DID_PARITY;274	case XEN_VSCSIIF_RSLT_HOST_ERROR:275		return DID_ERROR;276	case XEN_VSCSIIF_RSLT_HOST_RESET:277		return DID_RESET;278	case XEN_VSCSIIF_RSLT_HOST_BAD_INTR:279		return DID_BAD_INTR;280	case XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH:281		return DID_PASSTHROUGH;282	case XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR:283		return DID_SOFT_ERROR;284	case XEN_VSCSIIF_RSLT_HOST_IMM_RETRY:285		return DID_IMM_RETRY;286	case XEN_VSCSIIF_RSLT_HOST_REQUEUE:287		return DID_REQUEUE;288	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED:289		return DID_TRANSPORT_DISRUPTED;290	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST:291		return DID_TRANSPORT_FAILFAST;292	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL:293		return DID_TRANSPORT_MARGINAL;294	default:295		return DID_ERROR;296	}297}298 299static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,300				   struct vscsiif_response *ring_rsp)301{302	struct vscsifrnt_shadow *shadow;303	struct scsi_cmnd *sc;304	uint32_t id;305	uint8_t sense_len;306 307	id = ring_rsp->rqid;308	shadow = info->shadow[id];309	sc = shadow->sc;310 311	BUG_ON(sc == NULL);312 313	scsifront_gnttab_done(info, shadow);314	if (info->host_active == STATE_ERROR)315		return;316	scsifront_put_rqid(info, id);317 318	set_host_byte(sc, scsifront_host_byte(ring_rsp->rslt));319	set_status_byte(sc, XEN_VSCSIIF_RSLT_STATUS(ring_rsp->rslt));320	scsi_set_resid(sc, ring_rsp->residual_len);321 322	sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE,323			  ring_rsp->sense_len);324 325	if (sense_len)326		memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len);327 328	scsi_done(sc);329}330 331static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,332				    struct vscsiif_response *ring_rsp)333{334	uint16_t id = ring_rsp->rqid;335	unsigned long flags;336	struct vscsifrnt_shadow *shadow = info->shadow[id];337	int kick;338 339	spin_lock_irqsave(&info->shadow_lock, flags);340	shadow->wait_reset = 1;341	switch (shadow->rslt_reset) {342	case RSLT_RESET_WAITING:343		if (ring_rsp->rslt == XEN_VSCSIIF_RSLT_RESET_SUCCESS)344			shadow->rslt_reset = SUCCESS;345		else346			shadow->rslt_reset = FAILED;347		break;348	case RSLT_RESET_ERR:349		kick = _scsifront_put_rqid(info, id);350		spin_unlock_irqrestore(&info->shadow_lock, flags);351		kfree(shadow);352		if (kick)353			scsifront_wake_up(info);354		return;355	default:356		scsifront_set_error(info, "bad reset state");357		break;358	}359	spin_unlock_irqrestore(&info->shadow_lock, flags);360 361	wake_up(&shadow->wq_reset);362}363 364static void scsifront_do_response(struct vscsifrnt_info *info,365				  struct vscsiif_response *ring_rsp)366{367	struct vscsifrnt_shadow *shadow;368 369	if (ring_rsp->rqid >= VSCSIIF_MAX_REQS ||370	    !info->shadow[ring_rsp->rqid]->inflight) {371		scsifront_set_error(info, "illegal rqid returned by backend!");372		return;373	}374	shadow = info->shadow[ring_rsp->rqid];375	shadow->inflight = false;376 377	if (shadow->act == VSCSIIF_ACT_SCSI_CDB)378		scsifront_cdb_cmd_done(info, ring_rsp);379	else380		scsifront_sync_cmd_done(info, ring_rsp);381}382 383static int scsifront_ring_drain(struct vscsifrnt_info *info,384				unsigned int *eoiflag)385{386	struct vscsiif_response ring_rsp;387	RING_IDX i, rp;388	int more_to_do = 0;389 390	rp = READ_ONCE(info->ring.sring->rsp_prod);391	virt_rmb();	/* ordering required respective to backend */392	if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) {393		scsifront_set_error(info, "illegal number of responses");394		return 0;395	}396	for (i = info->ring.rsp_cons; i != rp; i++) {397		RING_COPY_RESPONSE(&info->ring, i, &ring_rsp);398		scsifront_do_response(info, &ring_rsp);399		if (info->host_active == STATE_ERROR)400			return 0;401		*eoiflag &= ~XEN_EOI_FLAG_SPURIOUS;402	}403 404	info->ring.rsp_cons = i;405 406	if (i != info->ring.req_prod_pvt)407		RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);408	else409		info->ring.sring->rsp_event = i + 1;410 411	return more_to_do;412}413 414static int scsifront_cmd_done(struct vscsifrnt_info *info,415			      unsigned int *eoiflag)416{417	int more_to_do;418	unsigned long flags;419 420	spin_lock_irqsave(info->host->host_lock, flags);421 422	more_to_do = scsifront_ring_drain(info, eoiflag);423 424	info->wait_ring_available = 0;425 426	spin_unlock_irqrestore(info->host->host_lock, flags);427 428	wake_up(&info->wq_sync);429 430	return more_to_do;431}432 433static irqreturn_t scsifront_irq_fn(int irq, void *dev_id)434{435	struct vscsifrnt_info *info = dev_id;436	unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;437 438	if (info->host_active == STATE_ERROR) {439		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);440		return IRQ_HANDLED;441	}442 443	while (scsifront_cmd_done(info, &eoiflag))444		/* Yield point for this unbounded loop. */445		cond_resched();446 447	xen_irq_lateeoi(irq, eoiflag);448 449	return IRQ_HANDLED;450}451 452static void scsifront_finish_all(struct vscsifrnt_info *info)453{454	unsigned int i, dummy;455	struct vscsiif_response resp;456 457	scsifront_ring_drain(info, &dummy);458 459	for (i = 0; i < VSCSIIF_MAX_REQS; i++) {460		if (test_bit(i, info->shadow_free_bitmap))461			continue;462		resp.rqid = i;463		resp.sense_len = 0;464		resp.rslt = DID_RESET << 16;465		resp.residual_len = 0;466		scsifront_do_response(info, &resp);467	}468}469 470static int map_data_for_request(struct vscsifrnt_info *info,471				struct scsi_cmnd *sc,472				struct vscsifrnt_shadow *shadow)473{474	grant_ref_t gref_head;475	struct page *page;476	int err, ref, ref_cnt = 0;477	int grant_ro = (sc->sc_data_direction == DMA_TO_DEVICE);478	unsigned int i, off, len, bytes;479	unsigned int data_len = scsi_bufflen(sc);480	unsigned int data_grants = 0, seg_grants = 0;481	struct scatterlist *sg;482	struct scsiif_request_segment *seg;483 484	if (sc->sc_data_direction == DMA_NONE || !data_len)485		return 0;486 487	scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i)488		data_grants += PFN_UP(sg->offset + sg->length);489 490	if (data_grants > VSCSIIF_SG_TABLESIZE) {491		if (data_grants > info->host->sg_tablesize) {492			shost_printk(KERN_ERR, info->host, KBUILD_MODNAME493			     "Unable to map request_buffer for command!\n");494			return -E2BIG;495		}496		seg_grants = vscsiif_grants_sg(data_grants);497		shadow->sg = kcalloc(data_grants,498			sizeof(struct scsiif_request_segment), GFP_ATOMIC);499		if (!shadow->sg)500			return -ENOMEM;501	}502	seg = shadow->sg ? : shadow->seg;503 504	err = gnttab_alloc_grant_references(seg_grants + data_grants,505					    &gref_head);506	if (err) {507		kfree(shadow->sg);508		shost_printk(KERN_ERR, info->host, KBUILD_MODNAME509			     "gnttab_alloc_grant_references() error\n");510		return -ENOMEM;511	}512 513	if (seg_grants) {514		page = virt_to_page(seg);515		off = offset_in_page(seg);516		len = sizeof(struct scsiif_request_segment) * data_grants;517		while (len > 0) {518			bytes = min_t(unsigned int, len, PAGE_SIZE - off);519 520			ref = gnttab_claim_grant_reference(&gref_head);521			BUG_ON(ref == -ENOSPC);522 523			gnttab_grant_foreign_access_ref(ref,524				info->dev->otherend_id,525				xen_page_to_gfn(page), 1);526			shadow->gref[ref_cnt] = ref;527			shadow->seg[ref_cnt].gref   = ref;528			shadow->seg[ref_cnt].offset = (uint16_t)off;529			shadow->seg[ref_cnt].length = (uint16_t)bytes;530 531			page++;532			len -= bytes;533			off = 0;534			ref_cnt++;535		}536		BUG_ON(seg_grants < ref_cnt);537		seg_grants = ref_cnt;538	}539 540	scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i) {541		page = sg_page(sg);542		off = sg->offset;543		len = sg->length;544 545		while (len > 0 && data_len > 0) {546			/*547			 * sg sends a scatterlist that is larger than548			 * the data_len it wants transferred for certain549			 * IO sizes.550			 */551			bytes = min_t(unsigned int, len, PAGE_SIZE - off);552			bytes = min(bytes, data_len);553 554			ref = gnttab_claim_grant_reference(&gref_head);555			BUG_ON(ref == -ENOSPC);556 557			gnttab_grant_foreign_access_ref(ref,558				info->dev->otherend_id,559				xen_page_to_gfn(page),560				grant_ro);561 562			shadow->gref[ref_cnt] = ref;563			seg->gref   = ref;564			seg->offset = (uint16_t)off;565			seg->length = (uint16_t)bytes;566 567			page++;568			seg++;569			len -= bytes;570			data_len -= bytes;571			off = 0;572			ref_cnt++;573		}574	}575 576	if (seg_grants)577		shadow->nr_segments = VSCSIIF_SG_GRANT | seg_grants;578	else579		shadow->nr_segments = (uint8_t)ref_cnt;580	shadow->nr_grants = ref_cnt;581 582	return 0;583}584 585static int scsifront_enter(struct vscsifrnt_info *info)586{587	if (info->pause)588		return 1;589	info->callers++;590	return 0;591}592 593static void scsifront_return(struct vscsifrnt_info *info)594{595	info->callers--;596	if (info->callers)597		return;598 599	if (!info->waiting_pause)600		return;601 602	info->waiting_pause = 0;603	wake_up(&info->wq_pause);604}605 606static int scsifront_queuecommand(struct Scsi_Host *shost,607				  struct scsi_cmnd *sc)608{609	struct vscsifrnt_info *info = shost_priv(shost);610	struct vscsifrnt_shadow *shadow = scsi_cmd_priv(sc);611	unsigned long flags;612	int err;613 614	if (info->host_active == STATE_ERROR)615		return SCSI_MLQUEUE_HOST_BUSY;616 617	sc->result = 0;618 619	shadow->sc  = sc;620	shadow->act = VSCSIIF_ACT_SCSI_CDB;621 622	spin_lock_irqsave(shost->host_lock, flags);623	if (scsifront_enter(info)) {624		spin_unlock_irqrestore(shost->host_lock, flags);625		return SCSI_MLQUEUE_HOST_BUSY;626	}627 628	err = map_data_for_request(info, sc, shadow);629	if (err < 0) {630		pr_debug("%s: err %d\n", __func__, err);631		scsifront_return(info);632		spin_unlock_irqrestore(shost->host_lock, flags);633		if (err == -ENOMEM)634			return SCSI_MLQUEUE_HOST_BUSY;635		sc->result = DID_ERROR << 16;636		scsi_done(sc);637		return 0;638	}639 640	if (scsifront_do_request(info, shadow)) {641		scsifront_gnttab_done(info, shadow);642		goto busy;643	}644 645	scsifront_return(info);646	spin_unlock_irqrestore(shost->host_lock, flags);647 648	return 0;649 650busy:651	scsifront_return(info);652	spin_unlock_irqrestore(shost->host_lock, flags);653	pr_debug("%s: busy\n", __func__);654	return SCSI_MLQUEUE_HOST_BUSY;655}656 657/*658 * Any exception handling (reset or abort) must be forwarded to the backend.659 * We have to wait until an answer is returned. This answer contains the660 * result to be returned to the requestor.661 */662static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)663{664	struct Scsi_Host *host = sc->device->host;665	struct vscsifrnt_info *info = shost_priv(host);666	struct vscsifrnt_shadow *shadow, *s = scsi_cmd_priv(sc);667	int err = 0;668 669	if (info->host_active == STATE_ERROR)670		return FAILED;671 672	shadow = kzalloc(sizeof(*shadow), GFP_NOIO);673	if (!shadow)674		return FAILED;675 676	shadow->act = act;677	shadow->rslt_reset = RSLT_RESET_WAITING;678	shadow->sc = sc;679	shadow->ref_rqid = s->rqid;680	init_waitqueue_head(&shadow->wq_reset);681 682	spin_lock_irq(host->host_lock);683 684	for (;;) {685		if (scsifront_enter(info))686			goto fail;687 688		if (!scsifront_do_request(info, shadow))689			break;690 691		scsifront_return(info);692		if (err)693			goto fail;694		info->wait_ring_available = 1;695		spin_unlock_irq(host->host_lock);696		err = wait_event_interruptible(info->wq_sync,697					       !info->wait_ring_available);698		spin_lock_irq(host->host_lock);699	}700 701	spin_unlock_irq(host->host_lock);702	err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset);703	spin_lock_irq(host->host_lock);704 705	if (!err) {706		err = shadow->rslt_reset;707		scsifront_put_rqid(info, shadow->rqid);708		kfree(shadow);709	} else {710		spin_lock(&info->shadow_lock);711		shadow->rslt_reset = RSLT_RESET_ERR;712		spin_unlock(&info->shadow_lock);713		err = FAILED;714	}715 716	scsifront_return(info);717	spin_unlock_irq(host->host_lock);718	return err;719 720fail:721	spin_unlock_irq(host->host_lock);722	kfree(shadow);723	return FAILED;724}725 726static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)727{728	pr_debug("%s\n", __func__);729	return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_ABORT);730}731 732static int scsifront_dev_reset_handler(struct scsi_cmnd *sc)733{734	pr_debug("%s\n", __func__);735	return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_RESET);736}737 738static int scsifront_sdev_configure(struct scsi_device *sdev)739{740	struct vscsifrnt_info *info = shost_priv(sdev->host);741	int err;742 743	if (info->host_active == STATE_ERROR)744		return -EIO;745 746	if (current == info->curr) {747		err = xenbus_printf(XBT_NIL, info->dev->nodename,748			      info->dev_state_path, "%d", XenbusStateConnected);749		if (err) {750			xenbus_dev_error(info->dev, err,751				"%s: writing dev_state_path", __func__);752			return err;753		}754	}755 756	return 0;757}758 759static void scsifront_sdev_destroy(struct scsi_device *sdev)760{761	struct vscsifrnt_info *info = shost_priv(sdev->host);762	int err;763 764	if (current == info->curr) {765		err = xenbus_printf(XBT_NIL, info->dev->nodename,766			      info->dev_state_path, "%d", XenbusStateClosed);767		if (err)768			xenbus_dev_error(info->dev, err,769				"%s: writing dev_state_path", __func__);770	}771}772 773static const struct scsi_host_template scsifront_sht = {774	.module			= THIS_MODULE,775	.name			= "Xen SCSI frontend driver",776	.queuecommand		= scsifront_queuecommand,777	.eh_abort_handler	= scsifront_eh_abort_handler,778	.eh_device_reset_handler = scsifront_dev_reset_handler,779	.slave_configure	= scsifront_sdev_configure,780	.slave_destroy		= scsifront_sdev_destroy,781	.cmd_per_lun		= VSCSIIF_DEFAULT_CMD_PER_LUN,782	.can_queue		= VSCSIIF_MAX_REQS,783	.this_id		= -1,784	.cmd_size		= sizeof(struct vscsifrnt_shadow),785	.sg_tablesize		= VSCSIIF_SG_TABLESIZE,786	.proc_name		= "scsifront",787};788 789static int scsifront_alloc_ring(struct vscsifrnt_info *info)790{791	struct xenbus_device *dev = info->dev;792	struct vscsiif_sring *sring;793	int err;794 795	/***** Frontend to Backend ring start *****/796	err = xenbus_setup_ring(dev, GFP_KERNEL, (void **)&sring, 1,797				&info->ring_ref);798	if (err)799		return err;800 801	XEN_FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);802 803	err = xenbus_alloc_evtchn(dev, &info->evtchn);804	if (err) {805		xenbus_dev_fatal(dev, err, "xenbus_alloc_evtchn");806		goto free_gnttab;807	}808 809	err = bind_evtchn_to_irq_lateeoi(info->evtchn);810	if (err <= 0) {811		xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq");812		goto free_gnttab;813	}814 815	info->irq = err;816 817	err = request_threaded_irq(info->irq, NULL, scsifront_irq_fn,818				   IRQF_ONESHOT, "scsifront", info);819	if (err) {820		xenbus_dev_fatal(dev, err, "request_threaded_irq");821		goto free_irq;822	}823 824	return 0;825 826/* free resource */827free_irq:828	unbind_from_irqhandler(info->irq, info);829free_gnttab:830	xenbus_teardown_ring((void **)&sring, 1, &info->ring_ref);831 832	return err;833}834 835static void scsifront_free_ring(struct vscsifrnt_info *info)836{837	unbind_from_irqhandler(info->irq, info);838	xenbus_teardown_ring((void **)&info->ring.sring, 1, &info->ring_ref);839}840 841static int scsifront_init_ring(struct vscsifrnt_info *info)842{843	struct xenbus_device *dev = info->dev;844	struct xenbus_transaction xbt;845	int err;846 847	pr_debug("%s\n", __func__);848 849	err = scsifront_alloc_ring(info);850	if (err)851		return err;852	pr_debug("%s: %u %u\n", __func__, info->ring_ref, info->evtchn);853 854again:855	err = xenbus_transaction_start(&xbt);856	if (err)857		xenbus_dev_fatal(dev, err, "starting transaction");858 859	err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",860			    info->ring_ref);861	if (err) {862		xenbus_dev_fatal(dev, err, "%s", "writing ring-ref");863		goto fail;864	}865 866	err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",867			    info->evtchn);868 869	if (err) {870		xenbus_dev_fatal(dev, err, "%s", "writing event-channel");871		goto fail;872	}873 874	err = xenbus_transaction_end(xbt, 0);875	if (err) {876		if (err == -EAGAIN)877			goto again;878		xenbus_dev_fatal(dev, err, "completing transaction");879		goto free_sring;880	}881 882	return 0;883 884fail:885	xenbus_transaction_end(xbt, 1);886free_sring:887	scsifront_free_ring(info);888 889	return err;890}891 892 893static int scsifront_probe(struct xenbus_device *dev,894			   const struct xenbus_device_id *id)895{896	struct vscsifrnt_info *info;897	struct Scsi_Host *host;898	int err = -ENOMEM;899	char name[TASK_COMM_LEN];900 901	host = scsi_host_alloc(&scsifront_sht, sizeof(*info));902	if (!host) {903		xenbus_dev_fatal(dev, err, "fail to allocate scsi host");904		return err;905	}906	info = shost_priv(host);907 908	dev_set_drvdata(&dev->dev, info);909	info->dev = dev;910 911	bitmap_fill(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);912 913	err = scsifront_init_ring(info);914	if (err) {915		scsi_host_put(host);916		return err;917	}918 919	init_waitqueue_head(&info->wq_sync);920	init_waitqueue_head(&info->wq_pause);921	spin_lock_init(&info->shadow_lock);922 923	snprintf(name, TASK_COMM_LEN, "vscsiif.%d", host->host_no);924 925	host->max_id      = VSCSIIF_MAX_TARGET;926	host->max_channel = 0;927	host->max_lun     = VSCSIIF_MAX_LUN;928	host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512;929	host->max_cmd_len = VSCSIIF_MAX_COMMAND_SIZE;930 931	err = scsi_add_host(host, &dev->dev);932	if (err) {933		dev_err(&dev->dev, "fail to add scsi host %d\n", err);934		goto free_sring;935	}936	info->host = host;937	info->host_active = STATE_ACTIVE;938 939	xenbus_switch_state(dev, XenbusStateInitialised);940 941	return 0;942 943free_sring:944	scsifront_free_ring(info);945	scsi_host_put(host);946	return err;947}948 949static int scsifront_resume(struct xenbus_device *dev)950{951	struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);952	struct Scsi_Host *host = info->host;953	int err;954 955	spin_lock_irq(host->host_lock);956 957	/* Finish all still pending commands. */958	scsifront_finish_all(info);959 960	spin_unlock_irq(host->host_lock);961 962	/* Reconnect to dom0. */963	scsifront_free_ring(info);964	err = scsifront_init_ring(info);965	if (err) {966		dev_err(&dev->dev, "fail to resume %d\n", err);967		scsi_host_put(host);968		return err;969	}970 971	xenbus_switch_state(dev, XenbusStateInitialised);972 973	return 0;974}975 976static int scsifront_suspend(struct xenbus_device *dev)977{978	struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);979	struct Scsi_Host *host = info->host;980	int err = 0;981 982	/* No new commands for the backend. */983	spin_lock_irq(host->host_lock);984	info->pause = 1;985	while (info->callers && !err) {986		info->waiting_pause = 1;987		info->wait_ring_available = 0;988		spin_unlock_irq(host->host_lock);989		wake_up(&info->wq_sync);990		err = wait_event_interruptible(info->wq_pause,991					       !info->waiting_pause);992		spin_lock_irq(host->host_lock);993	}994	spin_unlock_irq(host->host_lock);995	return err;996}997 998static void scsifront_remove(struct xenbus_device *dev)999{1000	struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);1001 1002	pr_debug("%s: %s removed\n", __func__, dev->nodename);1003 1004	mutex_lock(&scsifront_mutex);1005	if (info->host_active != STATE_INACTIVE) {1006		/* Scsi_host not yet removed */1007		scsi_remove_host(info->host);1008		info->host_active = STATE_INACTIVE;1009	}1010	mutex_unlock(&scsifront_mutex);1011 1012	scsifront_free_ring(info);1013	scsi_host_put(info->host);1014}1015 1016static void scsifront_disconnect(struct vscsifrnt_info *info)1017{1018	struct xenbus_device *dev = info->dev;1019	struct Scsi_Host *host = info->host;1020 1021	pr_debug("%s: %s disconnect\n", __func__, dev->nodename);1022 1023	/*1024	 * When this function is executed, all devices of1025	 * Frontend have been deleted.1026	 * Therefore, it need not block I/O before remove_host.1027	 */1028 1029	mutex_lock(&scsifront_mutex);1030	if (info->host_active != STATE_INACTIVE) {1031		scsi_remove_host(host);1032		info->host_active = STATE_INACTIVE;1033	}1034	mutex_unlock(&scsifront_mutex);1035 1036	xenbus_frontend_closed(dev);1037}1038 1039static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op)1040{1041	struct xenbus_device *dev = info->dev;1042	int i, err = 0;1043	char str[64];1044	char **dir;1045	unsigned int dir_n = 0;1046	unsigned int device_state;1047	unsigned int hst, chn, tgt, lun;1048	struct scsi_device *sdev;1049 1050	if (info->host_active == STATE_ERROR)1051		return;1052 1053	dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n);1054	if (IS_ERR(dir))1055		return;1056 1057	/* mark current task as the one allowed to modify device states */1058	BUG_ON(info->curr);1059	info->curr = current;1060 1061	for (i = 0; i < dir_n; i++) {1062		/* read status */1063		snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]);1064		err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u",1065				   &device_state);1066		if (XENBUS_EXIST_ERR(err))1067			continue;1068 1069		/* virtual SCSI device */1070		snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]);1071		err = xenbus_scanf(XBT_NIL, dev->otherend, str,1072				   "%u:%u:%u:%u", &hst, &chn, &tgt, &lun);1073		if (XENBUS_EXIST_ERR(err))1074			continue;1075 1076		/*1077		 * Front device state path, used in slave_configure called1078		 * on successfull scsi_add_device, and in slave_destroy called1079		 * on remove of a device.1080		 */1081		snprintf(info->dev_state_path, sizeof(info->dev_state_path),1082			 "vscsi-devs/%s/state", dir[i]);1083 1084		switch (op) {1085		case VSCSIFRONT_OP_ADD_LUN:1086			if (device_state != XenbusStateInitialised)1087				break;1088 1089			if (scsi_add_device(info->host, chn, tgt, lun)) {1090				dev_err(&dev->dev, "scsi_add_device\n");1091				err = xenbus_printf(XBT_NIL, dev->nodename,1092					      info->dev_state_path,1093					      "%d", XenbusStateClosed);1094				if (err)1095					xenbus_dev_error(dev, err,1096						"%s: writing dev_state_path", __func__);1097			}1098			break;1099		case VSCSIFRONT_OP_DEL_LUN:1100			if (device_state != XenbusStateClosing)1101				break;1102 1103			sdev = scsi_device_lookup(info->host, chn, tgt, lun);1104			if (sdev) {1105				scsi_remove_device(sdev);1106				scsi_device_put(sdev);1107			}1108			break;1109		case VSCSIFRONT_OP_READD_LUN:1110			if (device_state == XenbusStateConnected) {1111				err = xenbus_printf(XBT_NIL, dev->nodename,1112					      info->dev_state_path,1113					      "%d", XenbusStateConnected);1114				if (err)1115					xenbus_dev_error(dev, err,1116						"%s: writing dev_state_path", __func__);1117			}1118			break;1119		default:1120			break;1121		}1122	}1123 1124	info->curr = NULL;1125 1126	kfree(dir);1127}1128 1129static void scsifront_read_backend_params(struct xenbus_device *dev,1130					  struct vscsifrnt_info *info)1131{1132	unsigned int sg_grant, nr_segs;1133	struct Scsi_Host *host = info->host;1134 1135	sg_grant = xenbus_read_unsigned(dev->otherend, "feature-sg-grant", 0);1136	nr_segs = min_t(unsigned int, sg_grant, SG_ALL);1137	nr_segs = max_t(unsigned int, nr_segs, VSCSIIF_SG_TABLESIZE);1138	nr_segs = min_t(unsigned int, nr_segs,1139			VSCSIIF_SG_TABLESIZE * PAGE_SIZE /1140			sizeof(struct scsiif_request_segment));1141 1142	if (!info->pause && sg_grant)1143		dev_info(&dev->dev, "using up to %d SG entries\n", nr_segs);1144	else if (info->pause && nr_segs < host->sg_tablesize)1145		dev_warn(&dev->dev,1146			 "SG entries decreased from %d to %u - device may not work properly anymore\n",1147			 host->sg_tablesize, nr_segs);1148 1149	host->sg_tablesize = nr_segs;1150	host->max_sectors = (nr_segs - 1) * PAGE_SIZE / 512;1151}1152 1153static void scsifront_backend_changed(struct xenbus_device *dev,1154				      enum xenbus_state backend_state)1155{1156	struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);1157 1158	pr_debug("%s: %p %u %u\n", __func__, dev, dev->state, backend_state);1159 1160	switch (backend_state) {1161	case XenbusStateUnknown:1162	case XenbusStateInitialising:1163	case XenbusStateInitWait:1164	case XenbusStateInitialised:1165		break;1166 1167	case XenbusStateConnected:1168		scsifront_read_backend_params(dev, info);1169 1170		if (info->pause) {1171			scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_READD_LUN);1172			xenbus_switch_state(dev, XenbusStateConnected);1173			info->pause = 0;1174			return;1175		}1176 1177		if (xenbus_read_driver_state(dev->nodename) ==1178		    XenbusStateInitialised)1179			scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);1180 1181		if (dev->state != XenbusStateConnected)1182			xenbus_switch_state(dev, XenbusStateConnected);1183		break;1184 1185	case XenbusStateClosed:1186		if (dev->state == XenbusStateClosed)1187			break;1188		fallthrough;	/* Missed the backend's Closing state */1189	case XenbusStateClosing:1190		scsifront_disconnect(info);1191		break;1192 1193	case XenbusStateReconfiguring:1194		scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_DEL_LUN);1195		xenbus_switch_state(dev, XenbusStateReconfiguring);1196		break;1197 1198	case XenbusStateReconfigured:1199		scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);1200		xenbus_switch_state(dev, XenbusStateConnected);1201		break;1202	}1203}1204 1205static const struct xenbus_device_id scsifront_ids[] = {1206	{ "vscsi" },1207	{ "" }1208};1209 1210static struct xenbus_driver scsifront_driver = {1211	.ids			= scsifront_ids,1212	.probe			= scsifront_probe,1213	.remove			= scsifront_remove,1214	.resume			= scsifront_resume,1215	.suspend		= scsifront_suspend,1216	.otherend_changed	= scsifront_backend_changed,1217};1218 1219static int __init scsifront_init(void)1220{1221	if (!xen_domain())1222		return -ENODEV;1223 1224	return xenbus_register_frontend(&scsifront_driver);1225}1226module_init(scsifront_init);1227 1228static void __exit scsifront_exit(void)1229{1230	xenbus_unregister_driver(&scsifront_driver);1231}1232module_exit(scsifront_exit);1233 1234MODULE_DESCRIPTION("Xen SCSI frontend driver");1235MODULE_LICENSE("GPL");1236MODULE_ALIAS("xen:vscsi");1237MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");1238