uas.c 30.6 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;
64
	struct list_head inflight_list;
G
Gerd Hoffmann 已提交
65
	struct list_head dead_list;
M
Matthew Wilcox 已提交
66 67 68
};

enum {
69
	SUBMIT_STATUS_URB	= (1 << 1),
M
Matthew Wilcox 已提交
70 71 72 73 74 75
	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),
76 77 78 79
	COMMAND_INFLIGHT        = (1 << 8),
	DATA_IN_URB_INFLIGHT    = (1 << 9),
	DATA_OUT_URB_INFLIGHT   = (1 << 10),
	COMMAND_COMPLETED       = (1 << 11),
80
	COMMAND_ABORTED         = (1 << 12),
81
	IS_IN_WORK_LIST         = (1 << 13),
M
Matthew Wilcox 已提交
82 83 84 85 86 87 88 89 90
};

/* 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;
91
	struct list_head list;
M
Matthew Wilcox 已提交
92 93 94 95 96
};

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

static void uas_do_work(struct work_struct *work)
{
G
Gerd Hoffmann 已提交
104 105
	struct uas_dev_info *devinfo =
		container_of(work, struct uas_dev_info, work);
M
Matthew Wilcox 已提交
106
	struct uas_cmd_info *cmdinfo;
G
Gerd Hoffmann 已提交
107
	unsigned long flags;
108
	int err;
M
Matthew Wilcox 已提交
109

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

	if (devinfo->resetting)
		goto out;

115
	list_for_each_entry(cmdinfo, &devinfo->inflight_list, list) {
M
Matthew Wilcox 已提交
116
		struct scsi_pointer *scp = (void *)cmdinfo;
G
Gerd Hoffmann 已提交
117 118
		struct scsi_cmnd *cmnd = container_of(scp, struct scsi_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
}

133
static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
134 135
			      struct uas_cmd_info *cmdinfo,
			      int result, const char *caller)
136 137 138 139 140
{
	struct scsi_pointer *scp = (void *)cmdinfo;
	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);

	uas_log_cmd_state(cmnd, caller);
141
	lockdep_assert_held(&devinfo->lock);
142 143 144
	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
	cmdinfo->state |= COMMAND_ABORTED;
	cmdinfo->state &= ~IS_IN_WORK_LIST;
145
	cmnd->result = result << 16;
146
	list_move_tail(&cmdinfo->list, &devinfo->dead_list);
147 148
}

149 150
static void uas_abort_inflight(struct uas_dev_info *devinfo, int result,
			       const char *caller)
G
Gerd Hoffmann 已提交
151 152 153 154 155 156
{
	struct uas_cmd_info *cmdinfo;
	struct uas_cmd_info *temp;
	unsigned long flags;

	spin_lock_irqsave(&devinfo->lock, flags);
157
	list_for_each_entry_safe(cmdinfo, temp, &devinfo->inflight_list, list)
158
		uas_mark_cmd_dead(devinfo, cmdinfo, result, caller);
G
Gerd Hoffmann 已提交
159 160 161
	spin_unlock_irqrestore(&devinfo->lock, flags);
}

G
Gerd Hoffmann 已提交
162 163 164 165 166 167
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;

168
	lockdep_assert_held(&devinfo->lock);
G
Gerd Hoffmann 已提交
169 170 171 172
	cmdinfo->state |= IS_IN_WORK_LIST;
	schedule_work(&devinfo->work);
}

G
Gerd Hoffmann 已提交
173 174 175 176 177 178 179
static void uas_zap_dead(struct uas_dev_info *devinfo)
{
	struct uas_cmd_info *cmdinfo;
	struct uas_cmd_info *temp;
	unsigned long flags;

	spin_lock_irqsave(&devinfo->lock, flags);
180
	list_for_each_entry_safe(cmdinfo, temp, &devinfo->dead_list, list) {
G
Gerd Hoffmann 已提交
181 182 183 184
		struct scsi_pointer *scp = (void *)cmdinfo;
		struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd,
						      SCp);
		uas_log_cmd_state(cmnd, __func__);
185
		WARN_ON_ONCE(!(cmdinfo->state & COMMAND_ABORTED));
G
Gerd Hoffmann 已提交
186 187 188 189 190 191 192 193 194
		/* all urbs are killed, clear inflight bits */
		cmdinfo->state &= ~(COMMAND_INFLIGHT |
				    DATA_IN_URB_INFLIGHT |
				    DATA_OUT_URB_INFLIGHT);
		uas_try_complete(cmnd, __func__);
	}
	spin_unlock_irqrestore(&devinfo->lock, flags);
}

M
Matthew Wilcox 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
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;
239 240
}

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
/*
 * 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;
}

257 258 259 260
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller)
{
	struct uas_cmd_info *ci = (void *)&cmnd->SCp;

261 262
	scmd_printk(KERN_INFO, cmnd,
		    "%s %p tag %d, inflight:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
263
		    caller, cmnd, uas_get_tag(cmnd),
264 265 266 267 268 269 270 271 272 273
		    (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"   : "",
274
		    (ci->state & COMMAND_COMPLETED)     ? " done"  : "",
G
Gerd Hoffmann 已提交
275
		    (ci->state & COMMAND_ABORTED)       ? " abort" : "",
G
Gerd Hoffmann 已提交
276
		    (ci->state & IS_IN_WORK_LIST)       ? " work"  : "");
277 278 279 280 281
}

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

284
	lockdep_assert_held(&devinfo->lock);
285 286
	if (cmdinfo->state & (COMMAND_INFLIGHT |
			      DATA_IN_URB_INFLIGHT |
287
			      DATA_OUT_URB_INFLIGHT))
288
		return -EBUSY;
289
	WARN_ON_ONCE(cmdinfo->state & COMMAND_COMPLETED);
290 291 292
	cmdinfo->state |= COMMAND_COMPLETED;
	usb_free_urb(cmdinfo->data_in_urb);
	usb_free_urb(cmdinfo->data_out_urb);
293
	if (cmdinfo->state & COMMAND_ABORTED)
G
Gerd Hoffmann 已提交
294
		scmd_printk(KERN_INFO, cmnd, "abort completed\n");
295
	list_del(&cmdinfo->list);
296
	devinfo->cmnd[uas_get_tag(cmnd) - 1] = NULL;
297
	cmnd->scsi_done(cmnd);
298
	return 0;
M
Matthew Wilcox 已提交
299 300 301
}

static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
302
			  unsigned direction)
M
Matthew Wilcox 已提交
303 304 305 306
{
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
	int err;

307
	cmdinfo->state |= direction | SUBMIT_STATUS_URB;
M
Matthew Wilcox 已提交
308 309
	err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
	if (err) {
G
Gerd Hoffmann 已提交
310
		uas_add_work(cmdinfo);
M
Matthew Wilcox 已提交
311 312 313 314 315 316
	}
}

static void uas_stat_cmplt(struct urb *urb)
{
	struct iu *iu = urb->transfer_buffer;
317
	struct Scsi_Host *shost = urb->context;
H
Hans de Goede 已提交
318
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
319 320
	struct urb *data_in_urb = NULL;
	struct urb *data_out_urb = NULL;
M
Matthew Wilcox 已提交
321
	struct scsi_cmnd *cmnd;
322
	struct uas_cmd_info *cmdinfo;
G
Gerd Hoffmann 已提交
323
	unsigned long flags;
324
	unsigned int idx;
M
Matthew Wilcox 已提交
325

H
Hans de Goede 已提交
326 327 328 329 330
	spin_lock_irqsave(&devinfo->lock, flags);

	if (devinfo->resetting)
		goto out;

M
Matthew Wilcox 已提交
331
	if (urb->status) {
G
Gerd Hoffmann 已提交
332 333 334 335 336 337 338
		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 已提交
339
		goto out;
G
Gerd Hoffmann 已提交
340 341
	}

342 343 344 345
	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 已提交
346
		goto out;
347
	}
M
Matthew Wilcox 已提交
348

349
	cmnd = devinfo->cmnd[idx];
G
Gerd Hoffmann 已提交
350
	cmdinfo = (void *)&cmnd->SCp;
351 352 353 354 355 356

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

M
Matthew Wilcox 已提交
357 358 359 360 361 362 363 364
	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 已提交
365 366
		if (cmnd->result != 0) {
			/* cancel data transfers on error */
367 368
			data_in_urb = usb_get_urb(cmdinfo->data_in_urb);
			data_out_urb = usb_get_urb(cmdinfo->data_out_urb);
G
Gerd Hoffmann 已提交
369
		}
370 371
		cmdinfo->state &= ~COMMAND_INFLIGHT;
		uas_try_complete(cmnd, __func__);
M
Matthew Wilcox 已提交
372 373
		break;
	case IU_ID_READ_READY:
374 375 376 377 378
		if (!cmdinfo->data_in_urb ||
				(cmdinfo->state & DATA_IN_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected read rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
379 380 381
		uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
		break;
	case IU_ID_WRITE_READY:
382 383 384 385 386
		if (!cmdinfo->data_out_urb ||
				(cmdinfo->state & DATA_OUT_URB_INFLIGHT)) {
			scmd_printk(KERN_ERR, cmnd, "unexpected write rdy\n");
			break;
		}
M
Matthew Wilcox 已提交
387 388 389 390 391 392
		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 已提交
393
out:
G
Gerd Hoffmann 已提交
394
	usb_free_urb(urb);
G
Gerd Hoffmann 已提交
395
	spin_unlock_irqrestore(&devinfo->lock, flags);
396 397 398 399 400 401 402 403 404 405

	/* 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 已提交
406 407
}

408
static void uas_data_cmplt(struct urb *urb)
M
Matthew Wilcox 已提交
409
{
410 411
	struct scsi_cmnd *cmnd = urb->context;
	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
G
Gerd Hoffmann 已提交
412
	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
413
	struct scsi_data_buffer *sdb = NULL;
G
Gerd Hoffmann 已提交
414
	unsigned long flags;
415

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

418 419 420 421 422 423 424
	if (cmdinfo->data_in_urb == urb) {
		sdb = scsi_in(cmnd);
		cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
	} else if (cmdinfo->data_out_urb == urb) {
		sdb = scsi_out(cmnd);
		cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
	}
425 426
	if (sdb == NULL) {
		WARN_ON_ONCE(1);
H
Hans de Goede 已提交
427 428 429 430 431 432
		goto out;
	}

	if (devinfo->resetting)
		goto out;

433 434 435 436 437 438
	/* 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 已提交
439
	if (urb->status) {
H
Hans de Goede 已提交
440 441 442 443 444 445
		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 已提交
446 447 448 449 450
		/* error: no data transfered */
		sdb->resid = sdb->length;
	} else {
		sdb->resid = sdb->length - urb->actual_length;
	}
451
	uas_try_complete(cmnd, __func__);
H
Hans de Goede 已提交
452
out:
G
Gerd Hoffmann 已提交
453
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
454 455
}

H
Hans de Goede 已提交
456 457 458 459 460 461 462 463 464 465 466
static void uas_cmd_cmplt(struct urb *urb)
{
	struct scsi_cmnd *cmnd = urb->context;

	if (urb->status) {
		uas_log_cmd_state(cmnd, __func__);
		scmd_printk(KERN_ERR, cmnd, "cmd cmplt err %d\n", urb->status);
	}
	usb_free_urb(urb);
}

M
Matthew Wilcox 已提交
467
static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
468 469 470
				      unsigned int pipe, u16 stream_id,
				      struct scsi_cmnd *cmnd,
				      enum dma_data_direction dir)
M
Matthew Wilcox 已提交
471 472 473
{
	struct usb_device *udev = devinfo->udev;
	struct urb *urb = usb_alloc_urb(0, gfp);
474 475
	struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
		? scsi_in(cmnd) : scsi_out(cmnd);
M
Matthew Wilcox 已提交
476 477 478

	if (!urb)
		goto out;
479 480
	usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
			  uas_data_cmplt, cmnd);
481
	urb->stream_id = stream_id;
M
Matthew Wilcox 已提交
482 483 484 485 486 487 488
	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 已提交
489
				       struct Scsi_Host *shost, u16 stream_id)
M
Matthew Wilcox 已提交
490 491 492 493 494 495 496 497
{
	struct usb_device *udev = devinfo->udev;
	struct urb *urb = usb_alloc_urb(0, gfp);
	struct sense_iu *iu;

	if (!urb)
		goto out;

498
	iu = kzalloc(sizeof(*iu), gfp);
M
Matthew Wilcox 已提交
499 500 501 502
	if (!iu)
		goto free;

	usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
G
Gerd Hoffmann 已提交
503
						uas_stat_cmplt, shost);
M
Matthew Wilcox 已提交
504 505 506 507 508 509 510 511 512 513
	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,
514
					struct scsi_cmnd *cmnd)
M
Matthew Wilcox 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528
{
	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);
529
	iu = kzalloc(sizeof(*iu) + len, gfp);
M
Matthew Wilcox 已提交
530 531 532 533
	if (!iu)
		goto free;

	iu->iu_id = IU_ID_COMMAND;
534
	iu->tag = cpu_to_be16(uas_get_tag(cmnd));
C
Christoph Hellwig 已提交
535
	iu->prio_attr = UAS_SIMPLE_TAG;
M
Matthew Wilcox 已提交
536 537 538 539 540
	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,
H
Hans de Goede 已提交
541
							uas_cmd_cmplt, cmnd);
M
Matthew Wilcox 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554 555
	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 已提交
556
static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd,
557
					gfp_t gfp, unsigned int stream)
M
Matthew Wilcox 已提交
558
{
H
Hans de Goede 已提交
559
	struct Scsi_Host *shost = cmnd->device->host;
H
Hans de Goede 已提交
560
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
G
Gerd Hoffmann 已提交
561
	struct urb *urb;
H
Hans de Goede 已提交
562
	int err;
M
Matthew Wilcox 已提交
563

G
Gerd Hoffmann 已提交
564 565
	urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream);
	if (!urb)
566
		return NULL;
567
	usb_anchor_urb(urb, &devinfo->sense_urbs);
H
Hans de Goede 已提交
568 569
	err = usb_submit_urb(urb, gfp);
	if (err) {
570
		usb_unanchor_urb(urb);
H
Hans de Goede 已提交
571
		uas_log_cmd_state(cmnd, __func__);
G
Gerd Hoffmann 已提交
572
		shost_printk(KERN_INFO, shost,
H
Hans de Goede 已提交
573 574
			     "sense urb submission error %d stream %d\n",
			     err, stream);
G
Gerd Hoffmann 已提交
575
		usb_free_urb(urb);
576
		return NULL;
M
Matthew Wilcox 已提交
577
	}
578
	return urb;
G
Gerd Hoffmann 已提交
579 580 581 582 583 584
}

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

588
	lockdep_assert_held(&devinfo->lock);
589
	if (cmdinfo->state & SUBMIT_STATUS_URB) {
H
Hans de Goede 已提交
590
		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
591 592
		if (!urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
593
		cmdinfo->state &= ~SUBMIT_STATUS_URB;
M
Matthew Wilcox 已提交
594 595 596 597
	}

	if (cmdinfo->state & ALLOC_DATA_IN_URB) {
		cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
598
					devinfo->data_in_pipe, cmdinfo->stream,
599
					cmnd, DMA_FROM_DEVICE);
M
Matthew Wilcox 已提交
600 601 602 603 604 605
		if (!cmdinfo->data_in_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_IN_URB;
	}

	if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
606
		usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs);
H
Hans de Goede 已提交
607 608
		err = usb_submit_urb(cmdinfo->data_in_urb, gfp);
		if (err) {
609
			usb_unanchor_urb(cmdinfo->data_in_urb);
H
Hans de Goede 已提交
610
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
611
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
612 613
				"data in urb submission error %d stream %d\n",
				err, cmdinfo->data_in_urb->stream_id);
M
Matthew Wilcox 已提交
614 615 616
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
		cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
617
		cmdinfo->state |= DATA_IN_URB_INFLIGHT;
M
Matthew Wilcox 已提交
618 619 620 621
	}

	if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
		cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
622
					devinfo->data_out_pipe, cmdinfo->stream,
623
					cmnd, DMA_TO_DEVICE);
M
Matthew Wilcox 已提交
624 625 626 627 628 629
		if (!cmdinfo->data_out_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
	}

	if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
630
		usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs);
H
Hans de Goede 已提交
631 632
		err = usb_submit_urb(cmdinfo->data_out_urb, gfp);
		if (err) {
633
			usb_unanchor_urb(cmdinfo->data_out_urb);
H
Hans de Goede 已提交
634
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
635
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
636 637
				"data out urb submission error %d stream %d\n",
				err, cmdinfo->data_out_urb->stream_id);
M
Matthew Wilcox 已提交
638 639 640
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
		cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
641
		cmdinfo->state |= DATA_OUT_URB_INFLIGHT;
M
Matthew Wilcox 已提交
642 643 644
	}

	if (cmdinfo->state & ALLOC_CMD_URB) {
645
		cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd);
M
Matthew Wilcox 已提交
646 647 648 649 650 651
		if (!cmdinfo->cmd_urb)
			return SCSI_MLQUEUE_DEVICE_BUSY;
		cmdinfo->state &= ~ALLOC_CMD_URB;
	}

	if (cmdinfo->state & SUBMIT_CMD_URB) {
652
		usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs);
H
Hans de Goede 已提交
653 654
		err = usb_submit_urb(cmdinfo->cmd_urb, gfp);
		if (err) {
655
			usb_unanchor_urb(cmdinfo->cmd_urb);
H
Hans de Goede 已提交
656
			uas_log_cmd_state(cmnd, __func__);
M
Matthew Wilcox 已提交
657
			scmd_printk(KERN_INFO, cmnd,
H
Hans de Goede 已提交
658
				    "cmd urb submission error %d\n", err);
M
Matthew Wilcox 已提交
659 660
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
661
		cmdinfo->cmd_urb = NULL;
M
Matthew Wilcox 已提交
662
		cmdinfo->state &= ~SUBMIT_CMD_URB;
663
		cmdinfo->state |= COMMAND_INFLIGHT;
M
Matthew Wilcox 已提交
664 665 666 667 668
	}

	return 0;
}

J
Jeff Garzik 已提交
669
static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
M
Matthew Wilcox 已提交
670 671 672 673 674
					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 已提交
675
	unsigned long flags;
676
	unsigned int stream;
M
Matthew Wilcox 已提交
677 678 679 680
	int err;

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

681 682 683 684 685 686 687 688 689
	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;
	}

690 691
	spin_lock_irqsave(&devinfo->lock, flags);

692 693 694
	if (devinfo->resetting) {
		cmnd->result = DID_ERROR << 16;
		cmnd->scsi_done(cmnd);
695
		spin_unlock_irqrestore(&devinfo->lock, flags);
696 697 698
		return 0;
	}

699 700
	stream = uas_get_tag(cmnd);
	if (devinfo->cmnd[stream - 1]) {
G
Gerd Hoffmann 已提交
701
		spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
702
		return SCSI_MLQUEUE_DEVICE_BUSY;
G
Gerd Hoffmann 已提交
703
	}
M
Matthew Wilcox 已提交
704 705 706

	cmnd->scsi_done = done;

707 708
	memset(cmdinfo, 0, sizeof(*cmdinfo));
	cmdinfo->stream = stream;
709
	cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB;
M
Matthew Wilcox 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722 723

	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) {
724
		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
M
Matthew Wilcox 已提交
725 726 727 728 729 730
		cmdinfo->stream = 0;
	}

	err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
	if (err) {
		/* If we did nothing, give up now */
731
		if (cmdinfo->state & SUBMIT_STATUS_URB) {
G
Gerd Hoffmann 已提交
732
			spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
733 734
			return SCSI_MLQUEUE_DEVICE_BUSY;
		}
G
Gerd Hoffmann 已提交
735
		uas_add_work(cmdinfo);
M
Matthew Wilcox 已提交
736 737
	}

738
	devinfo->cmnd[stream - 1] = cmnd;
739
	list_add_tail(&cmdinfo->list, &devinfo->inflight_list);
G
Gerd Hoffmann 已提交
740
	spin_unlock_irqrestore(&devinfo->lock, flags);
M
Matthew Wilcox 已提交
741 742 743
	return 0;
}

J
Jeff Garzik 已提交
744 745
static DEF_SCSI_QCMD(uas_queuecommand)

M
Matthew Wilcox 已提交
746 747 748 749 750
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 已提交
751
	unsigned long flags;
G
Gerd Hoffmann 已提交
752
	int err;
M
Matthew Wilcox 已提交
753

H
Hans de Goede 已提交
754 755 756 757 758 759 760
	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 已提交
761
	shost_printk(KERN_INFO, sdev->host, "%s start\n", __func__);
H
Hans de Goede 已提交
762 763

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

767
	uas_abort_inflight(devinfo, DID_RESET, __func__);
768
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
G
Gerd Hoffmann 已提交
769 770
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
G
Gerd Hoffmann 已提交
771
	uas_zap_dead(devinfo);
G
Gerd Hoffmann 已提交
772
	err = usb_reset_device(udev);
H
Hans de Goede 已提交
773 774

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

H
Hans de Goede 已提交
778 779
	usb_unlock_device(udev);

G
Gerd Hoffmann 已提交
780 781 782 783
	if (err) {
		shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__);
		return FAILED;
	}
M
Matthew Wilcox 已提交
784

G
Gerd Hoffmann 已提交
785 786
	shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__);
	return SUCCESS;
M
Matthew Wilcox 已提交
787 788 789 790
}

static int uas_slave_alloc(struct scsi_device *sdev)
{
H
Hans de Goede 已提交
791
	sdev->hostdata = (void *)sdev->host->hostdata;
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809

	/* 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 已提交
810 811 812 813 814 815
	return 0;
}

static int uas_slave_configure(struct scsi_device *sdev)
{
	struct uas_dev_info *devinfo = sdev->hostdata;
H
Hans de Goede 已提交
816 817 818 819

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

M
Matthew Wilcox 已提交
820
	scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
821
	scsi_activate_tcq(sdev, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
	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,
	.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,
};

840 841 842 843 844 845
#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 已提交
846
static struct usb_device_id uas_usb_ids[] = {
847
#	include "unusual_uas.h"
M
Matthew Wilcox 已提交
848 849 850 851 852 853 854 855
	{ 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);

856 857
#undef UNUSUAL_DEV

858 859 860 861 862 863 864 865 866 867 868 869 870
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);
}

871
static int uas_configure_endpoints(struct uas_dev_info *devinfo)
872 873 874 875 876 877 878 879
{
	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);
880 881 882 883 884 885 886 887 888 889 890
	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 已提交
891

892
	if (udev->speed != USB_SPEED_SUPER) {
893
		devinfo->qdepth = 32;
M
Matthew Wilcox 已提交
894 895
		devinfo->use_streams = 0;
	} else {
896
		devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
897
						    3, MAX_CMNDS, GFP_NOIO);
898 899
		if (devinfo->qdepth < 0)
			return devinfo->qdepth;
M
Matthew Wilcox 已提交
900 901
		devinfo->use_streams = 1;
	}
902 903

	return 0;
M
Matthew Wilcox 已提交
904 905
}

906 907 908 909 910 911 912 913
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);
914
	usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
915 916
}

M
Matthew Wilcox 已提交
917 918
static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
919 920
	int result = -ENOMEM;
	struct Scsi_Host *shost = NULL;
M
Matthew Wilcox 已提交
921 922 923
	struct uas_dev_info *devinfo;
	struct usb_device *udev = interface_to_usbdev(intf);

924 925 926
	if (!uas_use_uas_driver(intf, id))
		return -ENODEV;

927 928
	if (uas_switch_interface(udev, intf))
		return -ENODEV;
M
Matthew Wilcox 已提交
929

H
Hans de Goede 已提交
930 931
	shost = scsi_host_alloc(&uas_host_template,
				sizeof(struct uas_dev_info));
M
Matthew Wilcox 已提交
932
	if (!shost)
933
		goto set_alt0;
M
Matthew Wilcox 已提交
934 935 936

	shost->max_cmd_len = 16 + 252;
	shost->max_id = 1;
937 938
	shost->max_lun = 256;
	shost->max_channel = 0;
M
Matthew Wilcox 已提交
939 940
	shost->sg_tablesize = udev->bus->sg_tablesize;

H
Hans de Goede 已提交
941
	devinfo = (struct uas_dev_info *)shost->hostdata;
M
Matthew Wilcox 已提交
942 943
	devinfo->intf = intf;
	devinfo->udev = udev;
G
Gerd Hoffmann 已提交
944
	devinfo->resetting = 0;
H
Hans de Goede 已提交
945
	devinfo->shutdown = 0;
946 947
	devinfo->flags = id->driver_info;
	usb_stor_adjust_quirks(udev, &devinfo->flags);
948
	init_usb_anchor(&devinfo->cmd_urbs);
949 950
	init_usb_anchor(&devinfo->sense_urbs);
	init_usb_anchor(&devinfo->data_urbs);
G
Gerd Hoffmann 已提交
951
	spin_lock_init(&devinfo->lock);
G
Gerd Hoffmann 已提交
952
	INIT_WORK(&devinfo->work, uas_do_work);
953
	INIT_LIST_HEAD(&devinfo->inflight_list);
G
Gerd Hoffmann 已提交
954
	INIT_LIST_HEAD(&devinfo->dead_list);
955 956 957 958

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

960
	result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
M
Matthew Wilcox 已提交
961
	if (result)
962
		goto free_streams;
963

964
	usb_set_intfdata(intf, shost);
965 966
	result = scsi_add_host(shost, &intf->dev);
	if (result)
967
		goto free_streams;
968

M
Matthew Wilcox 已提交
969 970
	scsi_scan_host(shost);
	return result;
971

972
free_streams:
973
	uas_free_streams(devinfo);
974
	usb_set_intfdata(intf, NULL);
975 976
set_alt0:
	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
M
Matthew Wilcox 已提交
977 978 979 980 981 982 983
	if (shost)
		scsi_host_put(shost);
	return result;
}

static int uas_pre_reset(struct usb_interface *intf)
{
984
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
985
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
986 987
	unsigned long flags;

H
Hans de Goede 已提交
988 989 990
	if (devinfo->shutdown)
		return 0;

991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
	/* 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 已提交
1005 1006 1007 1008 1009
	return 0;
}

static int uas_post_reset(struct usb_interface *intf)
{
1010
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1011
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
1012 1013
	unsigned long flags;

H
Hans de Goede 已提交
1014 1015 1016
	if (devinfo->shutdown)
		return 0;

1017 1018 1019 1020 1021
	if (uas_configure_endpoints(devinfo) != 0) {
		shost_printk(KERN_ERR, shost,
			     "%s: alloc streams error after reset", __func__);
		return 1;
	}
1022 1023 1024 1025 1026 1027 1028

	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 已提交
1029 1030 1031
	return 0;
}

H
Hans de Goede 已提交
1032 1033 1034
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1035
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054

	/* 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 已提交
1055
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
	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 已提交
1071 1072 1073
static void uas_disconnect(struct usb_interface *intf)
{
	struct Scsi_Host *shost = usb_get_intfdata(intf);
H
Hans de Goede 已提交
1074
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1075
	unsigned long flags;
M
Matthew Wilcox 已提交
1076

H
Hans de Goede 已提交
1077
	spin_lock_irqsave(&devinfo->lock, flags);
G
Gerd Hoffmann 已提交
1078
	devinfo->resetting = 1;
H
Hans de Goede 已提交
1079 1080
	spin_unlock_irqrestore(&devinfo->lock, flags);

G
Gerd Hoffmann 已提交
1081
	cancel_work_sync(&devinfo->work);
1082
	uas_abort_inflight(devinfo, DID_NO_CONNECT, __func__);
1083
	usb_kill_anchored_urbs(&devinfo->cmd_urbs);
1084 1085
	usb_kill_anchored_urbs(&devinfo->sense_urbs);
	usb_kill_anchored_urbs(&devinfo->data_urbs);
G
Gerd Hoffmann 已提交
1086
	uas_zap_dead(devinfo);
G
Gerd Hoffmann 已提交
1087
	scsi_remove_host(shost);
1088
	uas_free_streams(devinfo);
H
Hans de Goede 已提交
1089
	scsi_host_put(shost);
M
Matthew Wilcox 已提交
1090 1091
}

H
Hans de Goede 已提交
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
/*
 * 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 已提交
1102
	struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
H
Hans de Goede 已提交
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112

	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 已提交
1113 1114 1115 1116 1117 1118
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 已提交
1119 1120 1121
	.suspend = uas_suspend,
	.resume = uas_resume,
	.reset_resume = uas_reset_resume,
H
Hans de Goede 已提交
1122
	.drvwrap.driver.shutdown = uas_shutdown,
M
Matthew Wilcox 已提交
1123 1124 1125
	.id_table = uas_usb_ids,
};

1126
module_usb_driver(uas_driver);
M
Matthew Wilcox 已提交
1127 1128

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