uas.c 30.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 674 675 676 677 678
	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;
	}

679 680
	spin_lock_irqsave(&devinfo->lock, flags);

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

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

	cmnd->scsi_done = done;

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

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

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

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

J
Jeff Garzik 已提交
732 733
static DEF_SCSI_QCMD(uas_queuecommand)

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 759 760
/*
 * 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);

761 762
	uas_free_unsubmitted_urbs(cmnd);

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

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

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

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

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

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

H
Hans de Goede 已提交
809 810
	usb_unlock_device(udev);

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

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

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

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

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

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

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

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

888 889
#undef UNUSUAL_DEV

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

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

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

	return 0;
M
Matthew Wilcox 已提交
936 937
}

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

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

956 957 958
	if (!uas_use_uas_driver(intf, id))
		return -ENODEV;

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

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

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

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

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

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

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

M
Matthew Wilcox 已提交
999 1000
	scsi_scan_host(shost);
	return result;
1001

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

static int uas_pre_reset(struct usb_interface *intf)
{
1014
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1015
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1016 1017
	unsigned long flags;

H
Hans de Goede 已提交
1018 1019 1020
	if (devinfo->shutdown)
		return 0;

1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
	/* Block new requests */
	spin_lock_irqsave(shost->host_lock, flags);
	scsi_block_requests(shost);
	spin_unlock_irqrestore(shost->host_lock, flags);

	/* Wait for any pending requests to complete */
	flush_work(&devinfo->work);
	if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) {
		shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
		return 1;
	}

	uas_free_streams(devinfo);

M
Matthew Wilcox 已提交
1035 1036 1037 1038 1039
	return 0;
}

static int uas_post_reset(struct usb_interface *intf)
{
1040
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1041
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1042 1043
	unsigned long flags;

H
Hans de Goede 已提交
1044 1045 1046
	if (devinfo->shutdown)
		return 0;

1047 1048 1049 1050 1051
	if (uas_configure_endpoints(devinfo) != 0) {
		shost_printk(KERN_ERR, shost,
			     "%s: alloc streams error after reset", __func__);
		return 1;
	}
1052 1053 1054 1055 1056 1057 1058

	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 已提交
1059 1060 1061
	return 0;
}

H
Hans de Goede 已提交
1062 1063 1064
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1065
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084

	/* Wait for any pending requests to complete */
	flush_work(&devinfo->work);
	if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) {
		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 已提交
1085
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
	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 已提交
1101 1102 1103
static void uas_disconnect(struct usb_interface *intf)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1104
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1105
	unsigned long flags;
M
Matthew Wilcox 已提交
1106

H
Hans de Goede 已提交
1107
	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
1108
	devinfo->resetting = 1;
H
Hans de Goede 已提交
1109 1110
	spin_unlock_irqrestore(&devinfo->lock, flags);

G
Gerd Hoffmann 已提交
1111
	cancel_work_sync(&devinfo->work);
1112
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
1113 1114
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
1115 1116
	uas_zap_pending(devinfo, DID_NO_CONNECT);

G
Gerd Hoffmann 已提交
1117
	scsi_remove_host(shost);
1118
	uas_free_streams(devinfo);
H
Hans de Goede 已提交
1119
	scsi_host_put(shost);
M
Matthew Wilcox 已提交
1120 1121
}

H
Hans de Goede 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
/*
 * 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 已提交
1132
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142

	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 已提交
1143 1144 1145 1146 1147 1148
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 已提交
1149 1150 1151
	.suspend = uas_suspend,
	.resume = uas_resume,
	.reset_resume = uas_reset_resume,
H
Hans de Goede 已提交
1152
	.drvwrap.driver.shutdown = uas_shutdown,
M
Matthew Wilcox 已提交
1153 1154 1155
	.id_table = uas_usb_ids,
};

1156
module_usb_driver(uas_driver);
M
Matthew Wilcox 已提交
1157 1158

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