uas.c 31.7 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
	COMMAND_INFLIGHT        = (1 << 8),
	DATA_IN_URB_INFLIGHT    = (1 << 9),
	DATA_OUT_URB_INFLIGHT   = (1 << 10),
H
Hans de Goede 已提交
77 78
	COMMAND_ABORTED         = (1 << 11),
	IS_IN_WORK_LIST         = (1 << 12),
M
Matthew Wilcox 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92
};

/* 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);
93
static void uas_do_work(struct work_struct *work);
G
Gerd Hoffmann 已提交
94
static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller);
95
static void uas_free_streams(struct uas_dev_info *devinfo);
G
Gerd Hoffmann 已提交
96
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller);
M
Matthew Wilcox 已提交
97 98 99

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

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

	if (devinfo->resetting)
		goto out;

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

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

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

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

G
Gerd Hoffmann 已提交
132 133 134 135 136 137
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;

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

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

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

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

M
Matthew Wilcox 已提交
167 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
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;
211 212
}

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
/*
 * 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;
}

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

233
	scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
234
		    "%s tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ",
H
Hans de Goede 已提交
235
		    caller, uas_get_tag(cmnd),
236 237 238 239 240 241 242 243 244 245
		    (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"   : "",
G
Gerd Hoffmann 已提交
246
		    (ci->state & COMMAND_ABORTED)       ? " abort" : "",
G
Gerd Hoffmann 已提交
247
		    (ci->state & IS_IN_WORK_LIST)       ? " work"  : "");
H
Hans de Goede 已提交
248
	scsi_print_command(cmnd);
249 250
}

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
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);
}

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

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

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

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

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

H
Hans de Goede 已提交
312 313 314 315 316
	spin_lock_irqsave(&devinfo->lock, flags);

	if (devinfo->resetting)
		goto out;

M
Matthew Wilcox 已提交
317
	if (urb->status) {
318
		if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
G
Gerd Hoffmann 已提交
319 320 321
			dev_err(&urb->dev->dev, "stat urb: status %d\n",
				urb->status);
		}
H
Hans de Goede 已提交
322
		goto out;
G
Gerd Hoffmann 已提交
323 324
	}

325 326 327 328
	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 已提交
329
		goto out;
330
	}
M
Matthew Wilcox 已提交
331

332
	cmnd = devinfo->cmnd[idx];
G
Gerd Hoffmann 已提交
333
	cmdinfo = (void *)&cmnd->SCp;
334 335 336 337 338 339

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

M
Matthew Wilcox 已提交
340 341 342 343 344 345 346 347
	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 已提交
348 349
		if (cmnd->result != 0) {
			/* cancel data transfers on error */
350 351
			data_in_urb = usb_get_urb(cmdinfo->data_in_urb);
			data_out_urb = usb_get_urb(cmdinfo->data_out_urb);
G
Gerd Hoffmann 已提交
352
		}
353 354
		cmdinfo->state &= ~COMMAND_INFLIGHT;
		uas_try_complete(cmnd, __func__);
M
Matthew Wilcox 已提交
355 356
		break;
	case IU_ID_READ_READY:
357 358 359 360 361
		if (!cmdinfo->data_in_urb ||
				(cmdinfo->state & DATA_IN_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected read rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
362 363 364
		uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
		break;
	case IU_ID_WRITE_READY:
365 366 367 368 369
		if (!cmdinfo->data_out_urb ||
				(cmdinfo->state & DATA_OUT_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected write rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
370 371 372 373 374 375
		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 已提交
376
out:
G
Gerd Hoffmann 已提交
377
	usb_free_urb(urb);
G
Gerd Hoffmann 已提交
378
	spin_unlock_irqrestore(&devinfo->lock, flags);
379 380 381 382 383 384 385 386 387 388

	/* 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 已提交
389 390
}

391
static void uas_data_cmplt(struct urb *urb)
M
Matthew Wilcox 已提交
392
{
393 394
	struct scsi_cmnd *cmnd = urb->context;
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
395
	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
396
	struct scsi_data_buffer *sdb = NULL;
G
Gerd Hoffmann 已提交
397
	unsigned long flags;
398

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

401 402 403
	if (cmdinfo->data_in_urb == urb) {
		sdb = scsi_in(cmnd);
		cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
404
		cmdinfo->data_in_urb = NULL;
405 406 407
	} else if (cmdinfo->data_out_urb == urb) {
		sdb = scsi_out(cmnd);
		cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
408
		cmdinfo->data_out_urb = NULL;
409
	}
410 411
	if (sdb == NULL) {
		WARN_ON_ONCE(1);
H
Hans de Goede 已提交
412 413 414 415 416 417
		goto out;
	}

	if (devinfo->resetting)
		goto out;

418 419 420 421 422 423
	/* 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 已提交
424
	if (urb->status) {
425
		if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
H
Hans de Goede 已提交
426 427 428 429 430
			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 已提交
431 432 433 434 435
		/* error: no data transfered */
		sdb->resid = sdb->length;
	} else {
		sdb->resid = sdb->length - urb->actual_length;
	}
436
	uas_try_complete(cmnd, __func__);
H
Hans de Goede 已提交
437
out:
438
	usb_free_urb(urb);
G
Gerd Hoffmann 已提交
439
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
440 441
}

H
Hans de Goede 已提交
442 443
static void uas_cmd_cmplt(struct urb *urb)
{
444 445
	if (urb->status)
		dev_err(&urb->dev->dev, "cmd cmplt err %d\n", urb->status);
H
Hans de Goede 已提交
446 447 448 449

	usb_free_urb(urb);
}

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

	if (!urb)
		goto out;
462 463
	usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
			  uas_data_cmplt, cmnd);
464
	urb->stream_id = stream_id;
M
Matthew Wilcox 已提交
465 466 467 468 469 470 471
	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 已提交
472
				       struct Scsi_Host *shost, u16 stream_id)
M
Matthew Wilcox 已提交
473 474 475 476 477 478 479 480
{
	struct usb_device *udev = devinfo->udev;
	struct urb *urb = usb_alloc_urb(0, gfp);
	struct sense_iu *iu;

	if (!urb)
		goto out;

481
	iu = kzalloc(sizeof(*iu), gfp);
M
Matthew Wilcox 已提交
482 483 484 485
	if (!iu)
		goto free;

	usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
G
Gerd Hoffmann 已提交
486
						uas_stat_cmplt, shost);
M
Matthew Wilcox 已提交
487 488 489 490 491 492 493 494 495 496
	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,
497
					struct scsi_cmnd *cmnd)
M
Matthew Wilcox 已提交
498 499 500 501 502 503 504 505 506 507 508 509 510 511
{
	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);
512
	iu = kzalloc(sizeof(*iu) + len, gfp);
M
Matthew Wilcox 已提交
513 514 515 516
	if (!iu)
		goto free;

	iu->iu_id = IU_ID_COMMAND;
517
	iu->tag = cpu_to_be16(uas_get_tag(cmnd));
C
Christoph Hellwig 已提交
518
	iu->prio_attr = UAS_SIMPLE_TAG;
M
Matthew Wilcox 已提交
519 520 521 522 523
	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,
524
							uas_cmd_cmplt, NULL);
M
Matthew Wilcox 已提交
525 526 527 528 529 530 531 532 533 534 535 536 537 538
	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 已提交
539
static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd,
540
					gfp_t gfp, unsigned int stream)
M
Matthew Wilcox 已提交
541
{
H
Hans de Goede 已提交
542
	struct Scsi_Host *shost = cmnd->device->host;
H
Hans de Goede 已提交
543
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
G
Gerd Hoffmann 已提交
544
	struct urb *urb;
H
Hans de Goede 已提交
545
	int err;
M
Matthew Wilcox 已提交
546

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

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;
568
	struct urb *urb;
H
Hans de Goede 已提交
569
	int err;
M
Matthew Wilcox 已提交
570

571
	lockdep_assert_held(&devinfo->lock);
572
	if (cmdinfo->state & SUBMIT_STATUS_URB) {
H
Hans de Goede 已提交
573
		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
574 575
		if (!urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
576
		cmdinfo->state &= ~SUBMIT_STATUS_URB;
M
Matthew Wilcox 已提交
577 578 579 580
	}

	if (cmdinfo->state & ALLOC_DATA_IN_URB) {
		cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
581
					devinfo->data_in_pipe, cmdinfo->stream,
582
					cmnd, DMA_FROM_DEVICE);
M
Matthew Wilcox 已提交
583 584 585 586 587 588
		if (!cmdinfo->data_in_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_IN_URB;
	}

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

	if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
		cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
605
					devinfo->data_out_pipe, cmdinfo->stream,
606
					cmnd, DMA_TO_DEVICE);
M
Matthew Wilcox 已提交
607 608 609 610 611 612
		if (!cmdinfo->data_out_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
	}

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

	if (cmdinfo->state & ALLOC_CMD_URB) {
628
		cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd);
M
Matthew Wilcox 已提交
629 630 631 632 633 634
		if (!cmdinfo->cmd_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_CMD_URB;
	}

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

	return 0;
}

J
Jeff Garzik 已提交
652
static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
M
Matthew Wilcox 已提交
653 654 655 656 657
					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 已提交
658
	unsigned long flags;
659
	unsigned int stream;
M
Matthew Wilcox 已提交
660 661 662 663
	int err;

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

664 665 666 667
	/* Re-check scsi_block_requests now that we've the host-lock */
	if (cmnd->device->host->host_self_blocked)
		return SCSI_MLQUEUE_DEVICE_BUSY;

668 669 670 671 672 673 674 675 676
	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;
	}

677 678
	spin_lock_irqsave(&devinfo->lock, flags);

679 680 681
	if (devinfo->resetting) {
		cmnd->result = DID_ERROR << 16;
		cmnd->scsi_done(cmnd);
682
		spin_unlock_irqrestore(&devinfo->lock, flags);
683 684 685
		return 0;
	}

686 687
	stream = uas_get_tag(cmnd);
	if (devinfo->cmnd[stream - 1]) {
G
Gerd Hoffmann 已提交
688
		spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
689
		return SCSI_MLQUEUE_DEVICE_BUSY;
G
Gerd Hoffmann 已提交
690
	}
M
Matthew Wilcox 已提交
691 692 693

	cmnd->scsi_done = done;

694 695
	memset(cmdinfo, 0, sizeof(*cmdinfo));
	cmdinfo->stream = stream;
696
	cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB;
M
Matthew Wilcox 已提交
697 698 699 700 701 702 703 704 705 706 707 708 709 710

	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) {
711
		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
M
Matthew Wilcox 已提交
712 713 714 715 716 717
		cmdinfo->stream = 0;
	}

	err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
	if (err) {
		/* If we did nothing, give up now */
718
		if (cmdinfo->state & SUBMIT_STATUS_URB) {
G
Gerd Hoffmann 已提交
719
			spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
720 721
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
G
Gerd Hoffmann 已提交
722
		uas_add_work(cmdinfo);
M
Matthew Wilcox 已提交
723 724
	}

725
	devinfo->cmnd[stream - 1] = cmnd;
G
Gerd Hoffmann 已提交
726
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
727 728 729
	return 0;
}

J
Jeff Garzik 已提交
730 731
static DEF_SCSI_QCMD(uas_queuecommand)

732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
/*
 * 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);

759 760
	uas_free_unsubmitted_urbs(cmnd);

761 762 763 764 765 766 767 768 769 770 771 772 773 774
	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 已提交
775 776 777 778 779
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 已提交
780
	unsigned long flags;
G
Gerd Hoffmann 已提交
781
	int err;
M
Matthew Wilcox 已提交
782

H
Hans de Goede 已提交
783 784 785 786 787 788 789
	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 已提交
790
	shost_printk(KERN_INFO, sdev->host, "%s start\n", __func__);
H
Hans de Goede 已提交
791 792

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

796
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
G
Gerd Hoffmann 已提交
797 798
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
799 800
	uas_zap_pending(devinfo, DID_RESET);

G
Gerd Hoffmann 已提交
801
	err = usb_reset_device(udev);
H
Hans de Goede 已提交
802 803

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

H
Hans de Goede 已提交
807 808
	usb_unlock_device(udev);

G
Gerd Hoffmann 已提交
809 810 811 812
	if (err) {
		shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__);
		return FAILED;
	}
M
Matthew Wilcox 已提交
813

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

static int uas_slave_alloc(struct scsi_device *sdev)
{
H
Hans de Goede 已提交
820
	sdev->hostdata = (void *)sdev->host->hostdata;
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838

	/* 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 已提交
839 840 841 842 843 844
	return 0;
}

static int uas_slave_configure(struct scsi_device *sdev)
{
	struct uas_dev_info *devinfo = sdev->hostdata;
H
Hans de Goede 已提交
845 846 847 848

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

M
Matthew Wilcox 已提交
849
	scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
850
	scsi_activate_tcq(sdev, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
851 852 853 854 855 856 857 858 859
	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,
860
	.eh_abort_handler = uas_eh_abort_handler,
M
Matthew Wilcox 已提交
861 862 863 864 865 866 867 868 869
	.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,
};

870 871 872 873 874 875
#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 已提交
876
static struct usb_device_id uas_usb_ids[] = {
877
#	include "unusual_uas.h"
M
Matthew Wilcox 已提交
878 879 880 881 882 883 884 885
	{ 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);

886 887
#undef UNUSUAL_DEV

888 889 890 891 892 893 894 895 896 897 898 899 900
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);
}

901
static int uas_configure_endpoints(struct uas_dev_info *devinfo)
902 903 904 905 906 907 908 909
{
	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);
910 911 912 913 914 915 916 917 918 919 920
	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 已提交
921

922
	if (udev->speed < USB_SPEED_SUPER) {
923
		devinfo->qdepth = 32;
M
Matthew Wilcox 已提交
924 925
		devinfo->use_streams = 0;
	} else {
926
		devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
927
						    3, MAX_CMNDS, GFP_NOIO);
928 929
		if (devinfo->qdepth < 0)
			return devinfo->qdepth;
M
Matthew Wilcox 已提交
930 931
		devinfo->use_streams = 1;
	}
932 933

	return 0;
M
Matthew Wilcox 已提交
934 935
}

936 937 938 939 940 941 942 943
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);
944
	usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
945 946
}

M
Matthew Wilcox 已提交
947 948
static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
949 950
	int result = -ENOMEM;
	struct Scsi_Host *shost = NULL;
M
Matthew Wilcox 已提交
951 952 953
	struct uas_dev_info *devinfo;
	struct usb_device *udev = interface_to_usbdev(intf);

954 955 956
	if (!uas_use_uas_driver(intf, id))
		return -ENODEV;

957 958
	if (uas_switch_interface(udev, intf))
		return -ENODEV;
M
Matthew Wilcox 已提交
959

H
Hans de Goede 已提交
960 961
	shost = scsi_host_alloc(&uas_host_template,
				sizeof(struct uas_dev_info));
M
Matthew Wilcox 已提交
962
	if (!shost)
963
		goto set_alt0;
M
Matthew Wilcox 已提交
964 965 966

	shost->max_cmd_len = 16 + 252;
	shost->max_id = 1;
967 968
	shost->max_lun = 256;
	shost->max_channel = 0;
M
Matthew Wilcox 已提交
969 970
	shost->sg_tablesize = udev->bus->sg_tablesize;

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

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

988
	result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
989
	if (result)
990
		goto free_streams;
991

992
	usb_set_intfdata(intf, shost);
993 994
	result = scsi_add_host(shost, &intf->dev);
	if (result)
995
		goto free_streams;
996

M
Matthew Wilcox 已提交
997 998
	scsi_scan_host(shost);
	return result;
999

1000
free_streams:
1001
	uas_free_streams(devinfo);
1002
	usb_set_intfdata(intf, NULL);
1003 1004
set_alt0:
	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
M
Matthew Wilcox 已提交
1005 1006 1007 1008 1009
	if (shost)
		scsi_host_put(shost);
	return result;
}

1010 1011 1012 1013 1014 1015 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
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 已提交
1058 1059
static int uas_pre_reset(struct usb_interface *intf)
{
1060
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1061
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1062 1063
	unsigned long flags;

H
Hans de Goede 已提交
1064 1065 1066
	if (devinfo->shutdown)
		return 0;

1067 1068 1069 1070 1071
	/* Block new requests */
	spin_lock_irqsave(shost->host_lock, flags);
	scsi_block_requests(shost);
	spin_unlock_irqrestore(shost->host_lock, flags);

1072
	if (uas_wait_for_pending_cmnds(devinfo) != 0) {
1073
		shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
1074
		scsi_unblock_requests(shost);
1075 1076 1077 1078 1079
		return 1;
	}

	uas_free_streams(devinfo);

M
Matthew Wilcox 已提交
1080 1081 1082 1083 1084
	return 0;
}

static int uas_post_reset(struct usb_interface *intf)
{
1085
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1086
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1087 1088
	unsigned long flags;

H
Hans de Goede 已提交
1089 1090 1091
	if (devinfo->shutdown)
		return 0;

1092 1093 1094 1095 1096
	if (uas_configure_endpoints(devinfo) != 0) {
		shost_printk(KERN_ERR, shost,
			     "%s: alloc streams error after reset", __func__);
		return 1;
	}
1097 1098 1099 1100 1101 1102 1103

	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 已提交
1104 1105 1106
	return 0;
}

H
Hans de Goede 已提交
1107 1108 1109
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1110
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1111

1112
	if (uas_wait_for_pending_cmnds(devinfo) != 0) {
H
Hans de Goede 已提交
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
		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 已提交
1128
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
	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 已提交
1144 1145 1146
static void uas_disconnect(struct usb_interface *intf)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1147
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1148
	unsigned long flags;
M
Matthew Wilcox 已提交
1149

H
Hans de Goede 已提交
1150
	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
1151
	devinfo->resetting = 1;
H
Hans de Goede 已提交
1152 1153
	spin_unlock_irqrestore(&devinfo->lock, flags);

G
Gerd Hoffmann 已提交
1154
	cancel_work_sync(&devinfo->work);
1155
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
1156 1157
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
1158 1159
	uas_zap_pending(devinfo, DID_NO_CONNECT);

G
Gerd Hoffmann 已提交
1160
	scsi_remove_host(shost);
1161
	uas_free_streams(devinfo);
H
Hans de Goede 已提交
1162
	scsi_host_put(shost);
M
Matthew Wilcox 已提交
1163 1164
}

H
Hans de Goede 已提交
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
/*
 * 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 已提交
1175
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185

	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 已提交
1186 1187 1188 1189 1190 1191
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 已提交
1192 1193 1194
	.suspend = uas_suspend,
	.resume = uas_resume,
	.reset_resume = uas_reset_resume,
H
Hans de Goede 已提交
1195
	.drvwrap.driver.shutdown = uas_shutdown,
M
Matthew Wilcox 已提交
1196 1197 1198
	.id_table = uas_usb_ids,
};

1199
module_usb_driver(uas_driver);
M
Matthew Wilcox 已提交
1200 1201

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