uas.c 31.9 KB
Newer Older
M
Matthew Wilcox 已提交
1 2 3 4
/*
 * USB Attached SCSI
 * Note that this is not the same as the USB Mass Storage driver
 *
5
 * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2014
M
Matthew Wilcox 已提交
6 7 8 9 10 11 12 13 14
 * Copyright Matthew Wilcox for Intel Corp, 2010
 * Copyright Sarah Sharp for Intel Corp, 2010
 *
 * Distributed under the terms of the GNU GPL, version two.
 */

#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/types.h>
15
#include <linux/module.h>
M
Matthew Wilcox 已提交
16
#include <linux/usb.h>
17
#include <linux/usb_usual.h>
18
#include <linux/usb/hcd.h>
M
Matthew Wilcox 已提交
19
#include <linux/usb/storage.h>
20
#include <linux/usb/uas.h>
M
Matthew Wilcox 已提交
21 22

#include <scsi/scsi.h>
23
#include <scsi/scsi_eh.h>
M
Matthew Wilcox 已提交
24 25 26 27 28 29
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>

30
#include "uas-detect.h"
31
#include "scsiglue.h"
32

33 34
#define MAX_CMNDS 256

M
Matthew Wilcox 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
/*
 * The r00-r01c specs define this version of the SENSE IU data structure.
 * It's still in use by several different firmware releases.
 */
struct sense_iu_old {
	__u8 iu_id;
	__u8 rsvd1;
	__be16 tag;
	__be16 len;
	__u8 status;
	__u8 service_response;
	__u8 sense[SCSI_SENSE_BUFFERSIZE];
};

struct uas_dev_info {
	struct usb_interface *intf;
	struct usb_device *udev;
52
	struct usb_anchor cmd_urbs;
53 54
	struct usb_anchor sense_urbs;
	struct usb_anchor data_urbs;
55
	unsigned long flags;
G
Gerd Hoffmann 已提交
56
	int qdepth, resetting;
M
Matthew Wilcox 已提交
57 58 59
	unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
	unsigned use_streams:1;
	unsigned uas_sense_old:1;
H
Hans de Goede 已提交
60
	unsigned shutdown:1;
61
	struct scsi_cmnd *cmnd[MAX_CMNDS];
G
Gerd Hoffmann 已提交
62
	spinlock_t lock;
G
Gerd Hoffmann 已提交
63
	struct work_struct work;
M
Matthew Wilcox 已提交
64 65 66
};

enum {
67
	SUBMIT_STATUS_URB	= (1 << 1),
M
Matthew Wilcox 已提交
68 69 70 71 72 73
	ALLOC_DATA_IN_URB	= (1 << 2),
	SUBMIT_DATA_IN_URB	= (1 << 3),
	ALLOC_DATA_OUT_URB	= (1 << 4),
	SUBMIT_DATA_OUT_URB	= (1 << 5),
	ALLOC_CMD_URB		= (1 << 6),
	SUBMIT_CMD_URB		= (1 << 7),
74 75 76 77
	COMMAND_INFLIGHT        = (1 << 8),
	DATA_IN_URB_INFLIGHT    = (1 << 9),
	DATA_OUT_URB_INFLIGHT   = (1 << 10),
	COMMAND_COMPLETED       = (1 << 11),
78
	COMMAND_ABORTED         = (1 << 12),
79
	IS_IN_WORK_LIST         = (1 << 13),
M
Matthew Wilcox 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93
};

/* Overrides scsi_pointer */
struct uas_cmd_info {
	unsigned int state;
	unsigned int stream;
	struct urb *cmd_urb;
	struct urb *data_in_urb;
	struct urb *data_out_urb;
};

/* I hate forward declarations, but I actually have a loop */
static int uas_submit_urbs(struct scsi_cmnd *cmnd,
				struct uas_dev_info *devinfo, gfp_t gfp);
94
static void uas_do_work(struct work_struct *work);
G
Gerd Hoffmann 已提交
95
static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller);
96
static void uas_free_streams(struct uas_dev_info *devinfo);
G
Gerd Hoffmann 已提交
97
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller);
M
Matthew Wilcox 已提交
98 99 100

static void uas_do_work(struct work_struct *work)
{
G
Gerd Hoffmann 已提交
101 102
	struct uas_dev_info *devinfo =
		container_of(work, struct uas_dev_info, work);
M
Matthew Wilcox 已提交
103
	struct uas_cmd_info *cmdinfo;
H
Hans de Goede 已提交
104
	struct scsi_cmnd *cmnd;
G
Gerd Hoffmann 已提交
105
	unsigned long flags;
H
Hans de Goede 已提交
106
	int i, err;
M
Matthew Wilcox 已提交
107

G
Gerd Hoffmann 已提交
108
	spin_lock_irqsave(&devinfo->lock, flags);
H
Hans de Goede 已提交
109 110 111 112

	if (devinfo->resetting)
		goto out;

H
Hans de Goede 已提交
113 114 115 116 117 118
	for (i = 0; i < devinfo->qdepth; i++) {
		if (!devinfo->cmnd[i])
			continue;

		cmnd = devinfo->cmnd[i];
		cmdinfo = (void *)&cmnd->SCp;
119 120 121 122

		if (!(cmdinfo->state & IS_IN_WORK_LIST))
			continue;

O
Oliver Neukum 已提交
123
		err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
124
		if (!err)
G
Gerd Hoffmann 已提交
125
			cmdinfo->state &= ~IS_IN_WORK_LIST;
126
		else
G
Gerd Hoffmann 已提交
127
			schedule_work(&devinfo->work);
M
Matthew Wilcox 已提交
128
	}
H
Hans de Goede 已提交
129
out:
G
Gerd Hoffmann 已提交
130
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
131 132
}

G
Gerd Hoffmann 已提交
133 134 135 136 137 138
static void uas_add_work(struct uas_cmd_info *cmdinfo)
{
	struct scsi_pointer *scp = (void *)cmdinfo;
	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
	struct uas_dev_info *devinfo = cmnd->device->hostdata;

139
	lockdep_assert_held(&devinfo->lock);
G
Gerd Hoffmann 已提交
140 141 142 143
	cmdinfo->state |= IS_IN_WORK_LIST;
	schedule_work(&devinfo->work);
}

144
static void uas_zap_pending(struct uas_dev_info *devinfo, int result)
G
Gerd Hoffmann 已提交
145 146
{
	struct uas_cmd_info *cmdinfo;
H
Hans de Goede 已提交
147
	struct scsi_cmnd *cmnd;
G
Gerd Hoffmann 已提交
148
	unsigned long flags;
H
Hans de Goede 已提交
149
	int i, err;
G
Gerd Hoffmann 已提交
150 151

	spin_lock_irqsave(&devinfo->lock, flags);
H
Hans de Goede 已提交
152 153 154 155 156 157
	for (i = 0; i < devinfo->qdepth; i++) {
		if (!devinfo->cmnd[i])
			continue;

		cmnd = devinfo->cmnd[i];
		cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
158
		uas_log_cmd_state(cmnd, __func__);
159 160
		/* Sense urbs were killed, clear COMMAND_INFLIGHT manually */
		cmdinfo->state &= ~COMMAND_INFLIGHT;
161
		cmnd->result = result << 16;
162 163
		err = uas_try_complete(cmnd, __func__);
		WARN_ON(err != 0);
G
Gerd Hoffmann 已提交
164 165 166 167
	}
	spin_unlock_irqrestore(&devinfo->lock, flags);
}

M
Matthew Wilcox 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
{
	struct sense_iu *sense_iu = urb->transfer_buffer;
	struct scsi_device *sdev = cmnd->device;

	if (urb->actual_length > 16) {
		unsigned len = be16_to_cpup(&sense_iu->len);
		if (len + 16 != urb->actual_length) {
			int newlen = min(len + 16, urb->actual_length) - 16;
			if (newlen < 0)
				newlen = 0;
			sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
				"disagrees with IU sense data length %d, "
				"using %d bytes of sense data\n", __func__,
					urb->actual_length, len, newlen);
			len = newlen;
		}
		memcpy(cmnd->sense_buffer, sense_iu->sense, len);
	}

	cmnd->result = sense_iu->status;
}

static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
{
	struct sense_iu_old *sense_iu = urb->transfer_buffer;
	struct scsi_device *sdev = cmnd->device;

	if (urb->actual_length > 8) {
		unsigned len = be16_to_cpup(&sense_iu->len) - 2;
		if (len + 8 != urb->actual_length) {
			int newlen = min(len + 8, urb->actual_length) - 8;
			if (newlen < 0)
				newlen = 0;
			sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
				"disagrees with IU sense data length %d, "
				"using %d bytes of sense data\n", __func__,
					urb->actual_length, len, newlen);
			len = newlen;
		}
		memcpy(cmnd->sense_buffer, sense_iu->sense, len);
	}

	cmnd->result = sense_iu->status;
212 213
}

214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
/*
 * scsi-tags go from 0 - (nr_tags - 1), uas tags need to match stream-ids,
 * which go from 1 - nr_streams. And we use 1 for untagged commands.
 */
static int uas_get_tag(struct scsi_cmnd *cmnd)
{
	int tag;

	if (blk_rq_tagged(cmnd->request))
		tag = cmnd->request->tag + 2;
	else
		tag = 1;

	return tag;
}

230 231 232 233
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller)
{
	struct uas_cmd_info *ci = (void *)&cmnd->SCp;

234 235
	scmd_printk(KERN_INFO, cmnd,
		    "%s %p tag %d, inflight:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
236
		    caller, cmnd, uas_get_tag(cmnd),
237 238 239 240 241 242 243 244 245 246
		    (ci->state & SUBMIT_STATUS_URB)     ? " s-st"  : "",
		    (ci->state & ALLOC_DATA_IN_URB)     ? " a-in"  : "",
		    (ci->state & SUBMIT_DATA_IN_URB)    ? " s-in"  : "",
		    (ci->state & ALLOC_DATA_OUT_URB)    ? " a-out" : "",
		    (ci->state & SUBMIT_DATA_OUT_URB)   ? " s-out" : "",
		    (ci->state & ALLOC_CMD_URB)         ? " a-cmd" : "",
		    (ci->state & SUBMIT_CMD_URB)        ? " s-cmd" : "",
		    (ci->state & COMMAND_INFLIGHT)      ? " CMD"   : "",
		    (ci->state & DATA_IN_URB_INFLIGHT)  ? " IN"    : "",
		    (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT"   : "",
247
		    (ci->state & COMMAND_COMPLETED)     ? " done"  : "",
G
Gerd Hoffmann 已提交
248
		    (ci->state & COMMAND_ABORTED)       ? " abort" : "",
G
Gerd Hoffmann 已提交
249
		    (ci->state & IS_IN_WORK_LIST)       ? " work"  : "");
250 251
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
static void uas_free_unsubmitted_urbs(struct scsi_cmnd *cmnd)
{
	struct uas_cmd_info *cmdinfo;

	if (!cmnd)
		return;

	cmdinfo = (void *)&cmnd->SCp;

	if (cmdinfo->state & SUBMIT_CMD_URB)
		usb_free_urb(cmdinfo->cmd_urb);

	/* data urbs may have never gotten their submit flag set */
	if (!(cmdinfo->state & DATA_IN_URB_INFLIGHT))
		usb_free_urb(cmdinfo->data_in_urb);
	if (!(cmdinfo->state & DATA_OUT_URB_INFLIGHT))
		usb_free_urb(cmdinfo->data_out_urb);
}

271 272 273
static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
{
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
274
	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
275

276
	lockdep_assert_held(&devinfo->lock);
277 278
	if (cmdinfo->state & (COMMAND_INFLIGHT |
			      DATA_IN_URB_INFLIGHT |
279 280
			      DATA_OUT_URB_INFLIGHT |
			      COMMAND_ABORTED))
281
		return -EBUSY;
282
	WARN_ON_ONCE(cmdinfo->state & COMMAND_COMPLETED);
283
	cmdinfo->state |= COMMAND_COMPLETED;
284
	devinfo->cmnd[uas_get_tag(cmnd) - 1] = NULL;
285
	uas_free_unsubmitted_urbs(cmnd);
286
	cmnd->scsi_done(cmnd);
287
	return 0;
M
Matthew Wilcox 已提交
288 289 290
}

static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
291
			  unsigned direction)
M
Matthew Wilcox 已提交
292 293 294 295
{
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
	int err;

296
	cmdinfo->state |= direction | SUBMIT_STATUS_URB;
M
Matthew Wilcox 已提交
297 298
	err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
	if (err) {
G
Gerd Hoffmann 已提交
299
		uas_add_work(cmdinfo);
M
Matthew Wilcox 已提交
300 301 302 303 304 305
	}
}

static void uas_stat_cmplt(struct urb *urb)
{
	struct iu *iu = urb->transfer_buffer;
306
	struct Scsi_Host *shost = urb->context;
H
Hans de Goede 已提交
307
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
308 309
	struct urb *data_in_urb = NULL;
	struct urb *data_out_urb = NULL;
M
Matthew Wilcox 已提交
310
	struct scsi_cmnd *cmnd;
311
	struct uas_cmd_info *cmdinfo;
G
Gerd Hoffmann 已提交
312
	unsigned long flags;
313
	unsigned int idx;
M
Matthew Wilcox 已提交
314

H
Hans de Goede 已提交
315 316 317 318 319
	spin_lock_irqsave(&devinfo->lock, flags);

	if (devinfo->resetting)
		goto out;

M
Matthew Wilcox 已提交
320
	if (urb->status) {
G
Gerd Hoffmann 已提交
321 322 323 324 325 326 327
		if (urb->status == -ENOENT) {
			dev_err(&urb->dev->dev, "stat urb: killed, stream %d\n",
				urb->stream_id);
		} else {
			dev_err(&urb->dev->dev, "stat urb: status %d\n",
				urb->status);
		}
H
Hans de Goede 已提交
328
		goto out;
G
Gerd Hoffmann 已提交
329 330
	}

331 332 333 334
	idx = be16_to_cpup(&iu->tag) - 1;
	if (idx >= MAX_CMNDS || !devinfo->cmnd[idx]) {
		dev_err(&urb->dev->dev,
			"stat urb: no pending cmd for tag %d\n", idx + 1);
H
Hans de Goede 已提交
335
		goto out;
336
	}
M
Matthew Wilcox 已提交
337

338
	cmnd = devinfo->cmnd[idx];
G
Gerd Hoffmann 已提交
339
	cmdinfo = (void *)&cmnd->SCp;
340 341 342 343 344 345

	if (!(cmdinfo->state & COMMAND_INFLIGHT)) {
		scmd_printk(KERN_ERR, cmnd, "unexpected status cmplt\n");
		goto out;
	}

M
Matthew Wilcox 已提交
346 347 348 349 350 351 352 353
	switch (iu->iu_id) {
	case IU_ID_STATUS:
		if (urb->actual_length < 16)
			devinfo->uas_sense_old = 1;
		if (devinfo->uas_sense_old)
			uas_sense_old(urb, cmnd);
		else
			uas_sense(urb, cmnd);
G
Gerd Hoffmann 已提交
354 355
		if (cmnd->result != 0) {
			/* cancel data transfers on error */
356 357
			data_in_urb = usb_get_urb(cmdinfo->data_in_urb);
			data_out_urb = usb_get_urb(cmdinfo->data_out_urb);
G
Gerd Hoffmann 已提交
358
		}
359 360
		cmdinfo->state &= ~COMMAND_INFLIGHT;
		uas_try_complete(cmnd, __func__);
M
Matthew Wilcox 已提交
361 362
		break;
	case IU_ID_READ_READY:
363 364 365 366 367
		if (!cmdinfo->data_in_urb ||
				(cmdinfo->state & DATA_IN_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected read rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
368 369 370
		uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
		break;
	case IU_ID_WRITE_READY:
371 372 373 374 375
		if (!cmdinfo->data_out_urb ||
				(cmdinfo->state & DATA_OUT_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected write rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
376 377 378 379 380 381
		uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB);
		break;
	default:
		scmd_printk(KERN_ERR, cmnd,
			"Bogus IU (%d) received on status pipe\n", iu->iu_id);
	}
H
Hans de Goede 已提交
382
out:
G
Gerd Hoffmann 已提交
383
	usb_free_urb(urb);
G
Gerd Hoffmann 已提交
384
	spin_unlock_irqrestore(&devinfo->lock, flags);
385 386 387 388 389 390 391 392 393 394

	/* Unlinking of data urbs must be done without holding the lock */
	if (data_in_urb) {
		usb_unlink_urb(data_in_urb);
		usb_put_urb(data_in_urb);
	}
	if (data_out_urb) {
		usb_unlink_urb(data_out_urb);
		usb_put_urb(data_out_urb);
	}
M
Matthew Wilcox 已提交
395 396
}

397
static void uas_data_cmplt(struct urb *urb)
M
Matthew Wilcox 已提交
398
{
399 400
	struct scsi_cmnd *cmnd = urb->context;
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
401
	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
402
	struct scsi_data_buffer *sdb = NULL;
G
Gerd Hoffmann 已提交
403
	unsigned long flags;
404

G
Gerd Hoffmann 已提交
405
	spin_lock_irqsave(&devinfo->lock, flags);
H
Hans de Goede 已提交
406

407 408 409
	if (cmdinfo->data_in_urb == urb) {
		sdb = scsi_in(cmnd);
		cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
410
		cmdinfo->data_in_urb = NULL;
411 412 413
	} else if (cmdinfo->data_out_urb == urb) {
		sdb = scsi_out(cmnd);
		cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
414
		cmdinfo->data_out_urb = NULL;
415
	}
416 417
	if (sdb == NULL) {
		WARN_ON_ONCE(1);
H
Hans de Goede 已提交
418 419 420 421 422 423
		goto out;
	}

	if (devinfo->resetting)
		goto out;

424 425 426 427 428 429
	/* Data urbs should not complete before the cmd urb is submitted */
	if (cmdinfo->state & SUBMIT_CMD_URB) {
		scmd_printk(KERN_ERR, cmnd, "unexpected data cmplt\n");
		goto out;
	}

H
Hans de Goede 已提交
430
	if (urb->status) {
H
Hans de Goede 已提交
431 432 433 434 435 436
		if (urb->status != -ECONNRESET) {
			uas_log_cmd_state(cmnd, __func__);
			scmd_printk(KERN_ERR, cmnd,
				"data cmplt err %d stream %d\n",
				urb->status, urb->stream_id);
		}
G
Gerd Hoffmann 已提交
437 438 439 440 441
		/* error: no data transfered */
		sdb->resid = sdb->length;
	} else {
		sdb->resid = sdb->length - urb->actual_length;
	}
442
	uas_try_complete(cmnd, __func__);
H
Hans de Goede 已提交
443
out:
444
	usb_free_urb(urb);
G
Gerd Hoffmann 已提交
445
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
446 447
}

H
Hans de Goede 已提交
448 449
static void uas_cmd_cmplt(struct urb *urb)
{
450 451
	if (urb->status)
		dev_err(&urb->dev->dev, "cmd cmplt err %d\n", urb->status);
H
Hans de Goede 已提交
452 453 454 455

	usb_free_urb(urb);
}

M
Matthew Wilcox 已提交
456
static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
457 458 459
				      unsigned int pipe, u16 stream_id,
				      struct scsi_cmnd *cmnd,
				      enum dma_data_direction dir)
M
Matthew Wilcox 已提交
460 461 462
{
	struct usb_device *udev = devinfo->udev;
	struct urb *urb = usb_alloc_urb(0, gfp);
463 464
	struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
		? scsi_in(cmnd) : scsi_out(cmnd);
M
Matthew Wilcox 已提交
465 466 467

	if (!urb)
		goto out;
468 469
	usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
			  uas_data_cmplt, cmnd);
470
	urb->stream_id = stream_id;
M
Matthew Wilcox 已提交
471 472 473 474 475 476 477
	urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
	urb->sg = sdb->table.sgl;
 out:
	return urb;
}

static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
G
Gerd Hoffmann 已提交
478
				       struct Scsi_Host *shost, u16 stream_id)
M
Matthew Wilcox 已提交
479 480 481 482 483 484 485 486
{
	struct usb_device *udev = devinfo->udev;
	struct urb *urb = usb_alloc_urb(0, gfp);
	struct sense_iu *iu;

	if (!urb)
		goto out;

487
	iu = kzalloc(sizeof(*iu), gfp);
M
Matthew Wilcox 已提交
488 489 490 491
	if (!iu)
		goto free;

	usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
G
Gerd Hoffmann 已提交
492
						uas_stat_cmplt, shost);
M
Matthew Wilcox 已提交
493 494 495 496 497 498 499 500 501 502
	urb->stream_id = stream_id;
	urb->transfer_flags |= URB_FREE_BUFFER;
 out:
	return urb;
 free:
	usb_free_urb(urb);
	return NULL;
}

static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
503
					struct scsi_cmnd *cmnd)
M
Matthew Wilcox 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517
{
	struct usb_device *udev = devinfo->udev;
	struct scsi_device *sdev = cmnd->device;
	struct urb *urb = usb_alloc_urb(0, gfp);
	struct command_iu *iu;
	int len;

	if (!urb)
		goto out;

	len = cmnd->cmd_len - 16;
	if (len < 0)
		len = 0;
	len = ALIGN(len, 4);
518
	iu = kzalloc(sizeof(*iu) + len, gfp);
M
Matthew Wilcox 已提交
519 520 521 522
	if (!iu)
		goto free;

	iu->iu_id = IU_ID_COMMAND;
523
	iu->tag = cpu_to_be16(uas_get_tag(cmnd));
C
Christoph Hellwig 已提交
524
	iu->prio_attr = UAS_SIMPLE_TAG;
M
Matthew Wilcox 已提交
525 526 527 528 529
	iu->len = len;
	int_to_scsilun(sdev->lun, &iu->lun);
	memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);

	usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len,
530
							uas_cmd_cmplt, NULL);
M
Matthew Wilcox 已提交
531 532 533 534 535 536 537 538 539 540 541 542 543 544
	urb->transfer_flags |= URB_FREE_BUFFER;
 out:
	return urb;
 free:
	usb_free_urb(urb);
	return NULL;
}

/*
 * Why should I request the Status IU before sending the Command IU?  Spec
 * says to, but also says the device may receive them in any order.  Seems
 * daft to me.
 */

H
Hans de Goede 已提交
545
static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd,
546
					gfp_t gfp, unsigned int stream)
M
Matthew Wilcox 已提交
547
{
H
Hans de Goede 已提交
548
	struct Scsi_Host *shost = cmnd->device->host;
H
Hans de Goede 已提交
549
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
G
Gerd Hoffmann 已提交
550
	struct urb *urb;
H
Hans de Goede 已提交
551
	int err;
M
Matthew Wilcox 已提交
552

G
Gerd Hoffmann 已提交
553 554
	urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream);
	if (!urb)
555
		return NULL;
556
	usb_anchor_urb(urb, &devinfo->sense_urbs);
H
Hans de Goede 已提交
557 558
	err = usb_submit_urb(urb, gfp);
	if (err) {
559
		usb_unanchor_urb(urb);
H
Hans de Goede 已提交
560
		uas_log_cmd_state(cmnd, __func__);
G
Gerd Hoffmann 已提交
561
		shost_printk(KERN_INFO, shost,
H
Hans de Goede 已提交
562 563
			     "sense urb submission error %d stream %d\n",
			     err, stream);
G
Gerd Hoffmann 已提交
564
		usb_free_urb(urb);
565
		return NULL;
M
Matthew Wilcox 已提交
566
	}
567
	return urb;
G
Gerd Hoffmann 已提交
568 569 570 571 572 573
}

static int uas_submit_urbs(struct scsi_cmnd *cmnd,
			   struct uas_dev_info *devinfo, gfp_t gfp)
{
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
574
	struct urb *urb;
H
Hans de Goede 已提交
575
	int err;
M
Matthew Wilcox 已提交
576

577
	lockdep_assert_held(&devinfo->lock);
578
	if (cmdinfo->state & SUBMIT_STATUS_URB) {
H
Hans de Goede 已提交
579
		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
580 581
		if (!urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
582
		cmdinfo->state &= ~SUBMIT_STATUS_URB;
M
Matthew Wilcox 已提交
583 584 585 586
	}

	if (cmdinfo->state & ALLOC_DATA_IN_URB) {
		cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
587
					devinfo->data_in_pipe, cmdinfo->stream,
588
					cmnd, DMA_FROM_DEVICE);
M
Matthew Wilcox 已提交
589 590 591 592 593 594
		if (!cmdinfo->data_in_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_IN_URB;
	}

	if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
595
		usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs);
H
Hans de Goede 已提交
596 597
		err = usb_submit_urb(cmdinfo->data_in_urb, gfp);
		if (err) {
598
			usb_unanchor_urb(cmdinfo->data_in_urb);
H
Hans de Goede 已提交
599
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
600
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
601 602
				"data in urb submission error %d stream %d\n",
				err, cmdinfo->data_in_urb->stream_id);
M
Matthew Wilcox 已提交
603 604 605
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
		cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
606
		cmdinfo->state |= DATA_IN_URB_INFLIGHT;
M
Matthew Wilcox 已提交
607 608 609 610
	}

	if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
		cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
611
					devinfo->data_out_pipe, cmdinfo->stream,
612
					cmnd, DMA_TO_DEVICE);
M
Matthew Wilcox 已提交
613 614 615 616 617 618
		if (!cmdinfo->data_out_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
	}

	if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
619
		usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs);
H
Hans de Goede 已提交
620 621
		err = usb_submit_urb(cmdinfo->data_out_urb, gfp);
		if (err) {
622
			usb_unanchor_urb(cmdinfo->data_out_urb);
H
Hans de Goede 已提交
623
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
624
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
625 626
				"data out urb submission error %d stream %d\n",
				err, cmdinfo->data_out_urb->stream_id);
M
Matthew Wilcox 已提交
627 628 629
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
		cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
630
		cmdinfo->state |= DATA_OUT_URB_INFLIGHT;
M
Matthew Wilcox 已提交
631 632 633
	}

	if (cmdinfo->state & ALLOC_CMD_URB) {
634
		cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd);
M
Matthew Wilcox 已提交
635 636 637 638 639 640
		if (!cmdinfo->cmd_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_CMD_URB;
	}

	if (cmdinfo->state & SUBMIT_CMD_URB) {
641
		usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs);
H
Hans de Goede 已提交
642 643
		err = usb_submit_urb(cmdinfo->cmd_urb, gfp);
		if (err) {
644
			usb_unanchor_urb(cmdinfo->cmd_urb);
H
Hans de Goede 已提交
645
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
646
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
647
				    "cmd urb submission error %d\n", err);
M
Matthew Wilcox 已提交
648 649
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
650
		cmdinfo->cmd_urb = NULL;
M
Matthew Wilcox 已提交
651
		cmdinfo->state &= ~SUBMIT_CMD_URB;
652
		cmdinfo->state |= COMMAND_INFLIGHT;
M
Matthew Wilcox 已提交
653 654 655 656 657
	}

	return 0;
}

J
Jeff Garzik 已提交
658
static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
M
Matthew Wilcox 已提交
659 660 661 662 663
					void (*done)(struct scsi_cmnd *))
{
	struct scsi_device *sdev = cmnd->device;
	struct uas_dev_info *devinfo = sdev->hostdata;
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
664
	unsigned long flags;
665
	unsigned int stream;
M
Matthew Wilcox 已提交
666 667 668 669
	int err;

	BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));

670 671 672 673
	/* Re-check scsi_block_requests now that we've the host-lock */
	if (cmnd->device->host->host_self_blocked)
		return SCSI_MLQUEUE_DEVICE_BUSY;

674 675 676 677 678 679 680 681 682
	if ((devinfo->flags & US_FL_NO_ATA_1X) &&
			(cmnd->cmnd[0] == ATA_12 || cmnd->cmnd[0] == ATA_16)) {
		memcpy(cmnd->sense_buffer, usb_stor_sense_invalidCDB,
		       sizeof(usb_stor_sense_invalidCDB));
		cmnd->result = SAM_STAT_CHECK_CONDITION;
		cmnd->scsi_done(cmnd);
		return 0;
	}

683 684
	spin_lock_irqsave(&devinfo->lock, flags);

685 686 687
	if (devinfo->resetting) {
		cmnd->result = DID_ERROR << 16;
		cmnd->scsi_done(cmnd);
688
		spin_unlock_irqrestore(&devinfo->lock, flags);
689 690 691
		return 0;
	}

692 693
	stream = uas_get_tag(cmnd);
	if (devinfo->cmnd[stream - 1]) {
G
Gerd Hoffmann 已提交
694
		spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
695
		return SCSI_MLQUEUE_DEVICE_BUSY;
G
Gerd Hoffmann 已提交
696
	}
M
Matthew Wilcox 已提交
697 698 699

	cmnd->scsi_done = done;

700 701
	memset(cmdinfo, 0, sizeof(*cmdinfo));
	cmdinfo->stream = stream;
702
	cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB;
M
Matthew Wilcox 已提交
703 704 705 706 707 708 709 710 711 712 713 714 715 716

	switch (cmnd->sc_data_direction) {
	case DMA_FROM_DEVICE:
		cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
		break;
	case DMA_BIDIRECTIONAL:
		cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
	case DMA_TO_DEVICE:
		cmdinfo->state |= ALLOC_DATA_OUT_URB | SUBMIT_DATA_OUT_URB;
	case DMA_NONE:
		break;
	}

	if (!devinfo->use_streams) {
717
		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
M
Matthew Wilcox 已提交
718 719 720 721 722 723
		cmdinfo->stream = 0;
	}

	err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
	if (err) {
		/* If we did nothing, give up now */
724
		if (cmdinfo->state & SUBMIT_STATUS_URB) {
G
Gerd Hoffmann 已提交
725
			spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
726 727
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
G
Gerd Hoffmann 已提交
728
		uas_add_work(cmdinfo);
M
Matthew Wilcox 已提交
729 730
	}

731
	devinfo->cmnd[stream - 1] = cmnd;
G
Gerd Hoffmann 已提交
732
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
733 734 735
	return 0;
}

J
Jeff Garzik 已提交
736 737
static DEF_SCSI_QCMD(uas_queuecommand)

738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
/*
 * For now we do not support actually sending an abort to the device, so
 * this eh always fails. Still we must define it to make sure that we've
 * dropped all references to the cmnd in question once this function exits.
 */
static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
{
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
	struct urb *data_in_urb = NULL;
	struct urb *data_out_urb = NULL;
	unsigned long flags;

	spin_lock_irqsave(&devinfo->lock, flags);

	uas_log_cmd_state(cmnd, __func__);

	/* Ensure that try_complete does not call scsi_done */
	cmdinfo->state |= COMMAND_ABORTED;

	/* Drop all refs to this cmnd, kill data urbs to break their ref */
	devinfo->cmnd[uas_get_tag(cmnd) - 1] = NULL;
	if (cmdinfo->state & DATA_IN_URB_INFLIGHT)
		data_in_urb = usb_get_urb(cmdinfo->data_in_urb);
	if (cmdinfo->state & DATA_OUT_URB_INFLIGHT)
		data_out_urb = usb_get_urb(cmdinfo->data_out_urb);

765 766
	uas_free_unsubmitted_urbs(cmnd);

767 768 769 770 771 772 773 774 775 776 777 778 779 780
	spin_unlock_irqrestore(&devinfo->lock, flags);

	if (data_in_urb) {
		usb_kill_urb(data_in_urb);
		usb_put_urb(data_in_urb);
	}
	if (data_out_urb) {
		usb_kill_urb(data_out_urb);
		usb_put_urb(data_out_urb);
	}

	return FAILED;
}

M
Matthew Wilcox 已提交
781 782 783 784 785
static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
{
	struct scsi_device *sdev = cmnd->device;
	struct uas_dev_info *devinfo = sdev->hostdata;
	struct usb_device *udev = devinfo->udev;
H
Hans de Goede 已提交
786
	unsigned long flags;
G
Gerd Hoffmann 已提交
787
	int err;
M
Matthew Wilcox 已提交
788

H
Hans de Goede 已提交
789 790 791 792 793 794 795
	err = usb_lock_device_for_reset(udev, devinfo->intf);
	if (err) {
		shost_printk(KERN_ERR, sdev->host,
			     "%s FAILED to get lock err %d\n", __func__, err);
		return FAILED;
	}

G
Gerd Hoffmann 已提交
796
	shost_printk(KERN_INFO, sdev->host, "%s start\n", __func__);
H
Hans de Goede 已提交
797 798

	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
799
	devinfo->resetting = 1;
H
Hans de Goede 已提交
800 801
	spin_unlock_irqrestore(&devinfo->lock, flags);

802
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
G
Gerd Hoffmann 已提交
803 804
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
805 806
	uas_zap_pending(devinfo, DID_RESET);

G
Gerd Hoffmann 已提交
807
	err = usb_reset_device(udev);
H
Hans de Goede 已提交
808 809

	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
810
	devinfo->resetting = 0;
H
Hans de Goede 已提交
811
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
812

H
Hans de Goede 已提交
813 814
	usb_unlock_device(udev);

G
Gerd Hoffmann 已提交
815 816 817 818
	if (err) {
		shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__);
		return FAILED;
	}
M
Matthew Wilcox 已提交
819

G
Gerd Hoffmann 已提交
820 821
	shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__);
	return SUCCESS;
M
Matthew Wilcox 已提交
822 823 824 825
}

static int uas_slave_alloc(struct scsi_device *sdev)
{
H
Hans de Goede 已提交
826
	sdev->hostdata = (void *)sdev->host->hostdata;
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844

	/* USB has unusual DMA-alignment requirements: Although the
	 * starting address of each scatter-gather element doesn't matter,
	 * the length of each element except the last must be divisible
	 * by the Bulk maxpacket value.  There's currently no way to
	 * express this by block-layer constraints, so we'll cop out
	 * and simply require addresses to be aligned at 512-byte
	 * boundaries.  This is okay since most block I/O involves
	 * hardware sectors that are multiples of 512 bytes in length,
	 * and since host controllers up through USB 2.0 have maxpacket
	 * values no larger than 512.
	 *
	 * But it doesn't suffice for Wireless USB, where Bulk maxpacket
	 * values can be as large as 2048.  To make that work properly
	 * will require changes to the block layer.
	 */
	blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));

M
Matthew Wilcox 已提交
845 846 847 848 849 850
	return 0;
}

static int uas_slave_configure(struct scsi_device *sdev)
{
	struct uas_dev_info *devinfo = sdev->hostdata;
H
Hans de Goede 已提交
851 852 853 854

	if (devinfo->flags & US_FL_NO_REPORT_OPCODES)
		sdev->no_report_opcodes = 1;

M
Matthew Wilcox 已提交
855
	scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
856
	scsi_activate_tcq(sdev, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
857 858 859 860 861 862 863 864 865
	return 0;
}

static struct scsi_host_template uas_host_template = {
	.module = THIS_MODULE,
	.name = "uas",
	.queuecommand = uas_queuecommand,
	.slave_alloc = uas_slave_alloc,
	.slave_configure = uas_slave_configure,
866
	.eh_abort_handler = uas_eh_abort_handler,
M
Matthew Wilcox 已提交
867 868 869 870 871 872 873 874 875
	.eh_bus_reset_handler = uas_eh_bus_reset_handler,
	.can_queue = 65536,	/* Is there a limit on the _host_ ? */
	.this_id = -1,
	.sg_tablesize = SG_NONE,
	.cmd_per_lun = 1,	/* until we override it */
	.skip_settle_delay = 1,
	.ordered_tag = 1,
};

876 877 878 879 880 881
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
		    vendorName, productName, useProtocol, useTransport, \
		    initFunction, flags) \
{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
	.driver_info = (flags) }

M
Matthew Wilcox 已提交
882
static struct usb_device_id uas_usb_ids[] = {
883
#	include "unusual_uas.h"
M
Matthew Wilcox 已提交
884 885 886 887 888 889 890 891
	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) },
	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_UAS) },
	/* 0xaa is a prototype device I happen to have access to */
	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, 0xaa) },
	{ }
};
MODULE_DEVICE_TABLE(usb, uas_usb_ids);

892 893
#undef UNUSUAL_DEV

894 895 896 897 898 899 900 901 902 903 904 905 906
static int uas_switch_interface(struct usb_device *udev,
				struct usb_interface *intf)
{
	int alt;

	alt = uas_find_uas_alt_setting(intf);
	if (alt < 0)
		return alt;

	return usb_set_interface(udev,
			intf->altsetting[0].desc.bInterfaceNumber, alt);
}

907
static int uas_configure_endpoints(struct uas_dev_info *devinfo)
908 909 910 911 912 913 914 915
{
	struct usb_host_endpoint *eps[4] = { };
	struct usb_device *udev = devinfo->udev;
	int r;

	devinfo->uas_sense_old = 0;

	r = uas_find_endpoints(devinfo->intf->cur_altsetting, eps);
916 917 918 919 920 921 922 923 924 925 926
	if (r)
		return r;

	devinfo->cmd_pipe = usb_sndbulkpipe(udev,
					    usb_endpoint_num(&eps[0]->desc));
	devinfo->status_pipe = usb_rcvbulkpipe(udev,
					    usb_endpoint_num(&eps[1]->desc));
	devinfo->data_in_pipe = usb_rcvbulkpipe(udev,
					    usb_endpoint_num(&eps[2]->desc));
	devinfo->data_out_pipe = usb_sndbulkpipe(udev,
					    usb_endpoint_num(&eps[3]->desc));
M
Matthew Wilcox 已提交
927

928
	if (udev->speed < USB_SPEED_SUPER) {
929
		devinfo->qdepth = 32;
M
Matthew Wilcox 已提交
930 931
		devinfo->use_streams = 0;
	} else {
932
		devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
933
						    3, MAX_CMNDS, GFP_NOIO);
934 935
		if (devinfo->qdepth < 0)
			return devinfo->qdepth;
M
Matthew Wilcox 已提交
936 937
		devinfo->use_streams = 1;
	}
938 939

	return 0;
M
Matthew Wilcox 已提交
940 941
}

942 943 944 945 946 947 948 949
static void uas_free_streams(struct uas_dev_info *devinfo)
{
	struct usb_device *udev = devinfo->udev;
	struct usb_host_endpoint *eps[3];

	eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
	eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
	eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
950
	usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
951 952
}

M
Matthew Wilcox 已提交
953 954
static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
955 956
	int result = -ENOMEM;
	struct Scsi_Host *shost = NULL;
M
Matthew Wilcox 已提交
957 958 959
	struct uas_dev_info *devinfo;
	struct usb_device *udev = interface_to_usbdev(intf);

960 961 962
	if (!uas_use_uas_driver(intf, id))
		return -ENODEV;

963 964
	if (uas_switch_interface(udev, intf))
		return -ENODEV;
M
Matthew Wilcox 已提交
965

H
Hans de Goede 已提交
966 967
	shost = scsi_host_alloc(&uas_host_template,
				sizeof(struct uas_dev_info));
M
Matthew Wilcox 已提交
968
	if (!shost)
969
		goto set_alt0;
M
Matthew Wilcox 已提交
970 971 972

	shost->max_cmd_len = 16 + 252;
	shost->max_id = 1;
973 974
	shost->max_lun = 256;
	shost->max_channel = 0;
M
Matthew Wilcox 已提交
975 976
	shost->sg_tablesize = udev->bus->sg_tablesize;

H
Hans de Goede 已提交
977
	devinfo = (struct uas_dev_info *)shost->hostdata;
M
Matthew Wilcox 已提交
978 979
	devinfo->intf = intf;
	devinfo->udev = udev;
G
Gerd Hoffmann 已提交
980
	devinfo->resetting = 0;
H
Hans de Goede 已提交
981
	devinfo->shutdown = 0;
982 983
	devinfo->flags = id->driver_info;
	usb_stor_adjust_quirks(udev, &devinfo->flags);
984
	init_usb_anchor(&devinfo->cmd_urbs);
985 986
	init_usb_anchor(&devinfo->sense_urbs);
	init_usb_anchor(&devinfo->data_urbs);
G
Gerd Hoffmann 已提交
987
	spin_lock_init(&devinfo->lock);
G
Gerd Hoffmann 已提交
988
	INIT_WORK(&devinfo->work, uas_do_work);
989 990 991 992

	result = uas_configure_endpoints(devinfo);
	if (result)
		goto set_alt0;
M
Matthew Wilcox 已提交
993

994
	result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
995
	if (result)
996
		goto free_streams;
997

998
	usb_set_intfdata(intf, shost);
999 1000
	result = scsi_add_host(shost, &intf->dev);
	if (result)
1001
		goto free_streams;
1002

M
Matthew Wilcox 已提交
1003 1004
	scsi_scan_host(shost);
	return result;
1005

1006
free_streams:
1007
	uas_free_streams(devinfo);
1008
	usb_set_intfdata(intf, NULL);
1009 1010
set_alt0:
	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
M
Matthew Wilcox 已提交
1011 1012 1013 1014 1015
	if (shost)
		scsi_host_put(shost);
	return result;
}

1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
static int uas_cmnd_list_empty(struct uas_dev_info *devinfo)
{
	unsigned long flags;
	int i, r = 1;

	spin_lock_irqsave(&devinfo->lock, flags);

	for (i = 0; i < devinfo->qdepth; i++) {
		if (devinfo->cmnd[i]) {
			r = 0; /* Not empty */
			break;
		}
	}

	spin_unlock_irqrestore(&devinfo->lock, flags);

	return r;
}

/*
 * Wait for any pending cmnds to complete, on usb-2 sense_urbs may temporarily
 * get empty while there still is more work to do due to sense-urbs completing
 * with a READ/WRITE_READY iu code, so keep waiting until the list gets empty.
 */
static int uas_wait_for_pending_cmnds(struct uas_dev_info *devinfo)
{
	unsigned long start_time;
	int r;

	start_time = jiffies;
	do {
		flush_work(&devinfo->work);

		r = usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000);
		if (r == 0)
			return -ETIME;

		r = usb_wait_anchor_empty_timeout(&devinfo->data_urbs, 500);
		if (r == 0)
			return -ETIME;

		if (time_after(jiffies, start_time + 5 * HZ))
			return -ETIME;
	} while (!uas_cmnd_list_empty(devinfo));

	return 0;
}

M
Matthew Wilcox 已提交
1064 1065
static int uas_pre_reset(struct usb_interface *intf)
{
1066
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1067
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1068 1069
	unsigned long flags;

H
Hans de Goede 已提交
1070 1071 1072
	if (devinfo->shutdown)
		return 0;

1073 1074 1075 1076 1077
	/* Block new requests */
	spin_lock_irqsave(shost->host_lock, flags);
	scsi_block_requests(shost);
	spin_unlock_irqrestore(shost->host_lock, flags);

1078
	if (uas_wait_for_pending_cmnds(devinfo) != 0) {
1079
		shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
1080
		scsi_unblock_requests(shost);
1081 1082 1083 1084 1085
		return 1;
	}

	uas_free_streams(devinfo);

M
Matthew Wilcox 已提交
1086 1087 1088 1089 1090
	return 0;
}

static int uas_post_reset(struct usb_interface *intf)
{
1091
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1092
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1093 1094
	unsigned long flags;

H
Hans de Goede 已提交
1095 1096 1097
	if (devinfo->shutdown)
		return 0;

1098 1099 1100 1101 1102
	if (uas_configure_endpoints(devinfo) != 0) {
		shost_printk(KERN_ERR, shost,
			     "%s: alloc streams error after reset", __func__);
		return 1;
	}
1103 1104 1105 1106 1107 1108 1109

	spin_lock_irqsave(shost->host_lock, flags);
	scsi_report_bus_reset(shost, 0);
	spin_unlock_irqrestore(shost->host_lock, flags);

	scsi_unblock_requests(shost);

M
Matthew Wilcox 已提交
1110 1111 1112
	return 0;
}

H
Hans de Goede 已提交
1113 1114 1115
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1116
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1117

1118
	if (uas_wait_for_pending_cmnds(devinfo) != 0) {
H
Hans de Goede 已提交
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
		shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
		return -ETIME;
	}

	return 0;
}

static int uas_resume(struct usb_interface *intf)
{
	return 0;
}

static int uas_reset_resume(struct usb_interface *intf)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1134
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
	unsigned long flags;

	if (uas_configure_endpoints(devinfo) != 0) {
		shost_printk(KERN_ERR, shost,
			     "%s: alloc streams error after reset", __func__);
		return -EIO;
	}

	spin_lock_irqsave(shost->host_lock, flags);
	scsi_report_bus_reset(shost, 0);
	spin_unlock_irqrestore(shost->host_lock, flags);

	return 0;
}

M
Matthew Wilcox 已提交
1150 1151 1152
static void uas_disconnect(struct usb_interface *intf)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1153
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1154
	unsigned long flags;
M
Matthew Wilcox 已提交
1155

H
Hans de Goede 已提交
1156
	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
1157
	devinfo->resetting = 1;
H
Hans de Goede 已提交
1158 1159
	spin_unlock_irqrestore(&devinfo->lock, flags);

G
Gerd Hoffmann 已提交
1160
	cancel_work_sync(&devinfo->work);
1161
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
1162 1163
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
1164 1165
	uas_zap_pending(devinfo, DID_NO_CONNECT);

G
Gerd Hoffmann 已提交
1166
	scsi_remove_host(shost);
1167
	uas_free_streams(devinfo);
H
Hans de Goede 已提交
1168
	scsi_host_put(shost);
M
Matthew Wilcox 已提交
1169 1170
}

H
Hans de Goede 已提交
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
/*
 * Put the device back in usb-storage mode on shutdown, as some BIOS-es
 * hang on reboot when the device is still in uas mode. Note the reset is
 * necessary as some devices won't revert to usb-storage mode without it.
 */
static void uas_shutdown(struct device *dev)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1181
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191

	if (system_state != SYSTEM_RESTART)
		return;

	devinfo->shutdown = 1;
	uas_free_streams(devinfo);
	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
	usb_reset_device(udev);
}

M
Matthew Wilcox 已提交
1192 1193 1194 1195 1196 1197
static struct usb_driver uas_driver = {
	.name = "uas",
	.probe = uas_probe,
	.disconnect = uas_disconnect,
	.pre_reset = uas_pre_reset,
	.post_reset = uas_post_reset,
H
Hans de Goede 已提交
1198 1199 1200
	.suspend = uas_suspend,
	.resume = uas_resume,
	.reset_resume = uas_reset_resume,
H
Hans de Goede 已提交
1201
	.drvwrap.driver.shutdown = uas_shutdown,
M
Matthew Wilcox 已提交
1202 1203 1204
	.id_table = uas_usb_ids,
};

1205
module_usb_driver(uas_driver);
M
Matthew Wilcox 已提交
1206 1207

MODULE_LICENSE("GPL");
1208 1209
MODULE_AUTHOR(
	"Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp");