1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget 4 * 5 * ep0.c - Endpoint 0 handling 6 * 7 * Copyright 2017 IBM Corporation 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 #include <linux/delay.h> 19 #include <linux/ioport.h> 20 #include <linux/slab.h> 21 #include <linux/errno.h> 22 #include <linux/list.h> 23 #include <linux/interrupt.h> 24 #include <linux/proc_fs.h> 25 #include <linux/prefetch.h> 26 #include <linux/clk.h> 27 #include <linux/usb/gadget.h> 28 #include <linux/of.h> 29 #include <linux/of_gpio.h> 30 #include <linux/regmap.h> 31 #include <linux/dma-mapping.h> 32 33 #include "vhub.h" 34 35 int ast_vhub_reply(struct ast_vhub_ep *ep, char *ptr, int len) 36 { 37 struct usb_request *req = &ep->ep0.req.req; 38 int rc; 39 40 if (WARN_ON(ep->d_idx != 0)) 41 return std_req_stall; 42 if (WARN_ON(!ep->ep0.dir_in)) 43 return std_req_stall; 44 if (WARN_ON(len > AST_VHUB_EP0_MAX_PACKET)) 45 return std_req_stall; 46 if (WARN_ON(req->status == -EINPROGRESS)) 47 return std_req_stall; 48 49 req->buf = ptr; 50 req->length = len; 51 req->complete = NULL; 52 req->zero = true; 53 54 /* 55 * Call internal queue directly after dropping the lock. This is 56 * safe to do as the reply is always the last thing done when 57 * processing a SETUP packet, usually as a tail call 58 */ 59 spin_unlock(&ep->vhub->lock); 60 if (ep->ep.ops->queue(&ep->ep, req, GFP_ATOMIC)) 61 rc = std_req_stall; 62 else 63 rc = std_req_data; 64 spin_lock(&ep->vhub->lock); 65 return rc; 66 } 67 68 int __ast_vhub_simple_reply(struct ast_vhub_ep *ep, int len, ...) 69 { 70 u8 *buffer = ep->buf; 71 unsigned int i; 72 va_list args; 73 74 va_start(args, len); 75 76 /* Copy data directly into EP buffer */ 77 for (i = 0; i < len; i++) 78 buffer[i] = va_arg(args, int); 79 va_end(args); 80 81 /* req->buf NULL means data is already there */ 82 return ast_vhub_reply(ep, NULL, len); 83 } 84 85 void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep) 86 { 87 struct usb_ctrlrequest crq; 88 enum std_req_rc std_req_rc; 89 int rc = -ENODEV; 90 91 if (WARN_ON(ep->d_idx != 0)) 92 return; 93 94 /* 95 * Grab the setup packet from the chip and byteswap 96 * interesting fields 97 */ 98 memcpy_fromio(&crq, ep->ep0.setup, sizeof(crq)); 99 100 EPDBG(ep, "SETUP packet %02x/%02x/%04x/%04x/%04x [%s] st=%d\n", 101 crq.bRequestType, crq.bRequest, 102 le16_to_cpu(crq.wValue), 103 le16_to_cpu(crq.wIndex), 104 le16_to_cpu(crq.wLength), 105 (crq.bRequestType & USB_DIR_IN) ? "in" : "out", 106 ep->ep0.state); 107 108 /* Check our state, cancel pending requests if needed */ 109 if (ep->ep0.state != ep0_state_token) { 110 EPDBG(ep, "wrong state\n"); 111 ast_vhub_nuke(ep, 0); 112 goto stall; 113 } 114 115 /* Calculate next state for EP0 */ 116 ep->ep0.state = ep0_state_data; 117 ep->ep0.dir_in = !!(crq.bRequestType & USB_DIR_IN); 118 119 /* If this is the vHub, we handle requests differently */ 120 std_req_rc = std_req_driver; 121 if (ep->dev == NULL) { 122 if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) 123 std_req_rc = ast_vhub_std_hub_request(ep, &crq); 124 else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) 125 std_req_rc = ast_vhub_class_hub_request(ep, &crq); 126 else 127 std_req_rc = std_req_stall; 128 } else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) 129 std_req_rc = ast_vhub_std_dev_request(ep, &crq); 130 131 /* Act upon result */ 132 switch(std_req_rc) { 133 case std_req_complete: 134 goto complete; 135 case std_req_stall: 136 goto stall; 137 case std_req_driver: 138 break; 139 case std_req_data: 140 return; 141 } 142 143 /* Pass request up to the gadget driver */ 144 if (WARN_ON(!ep->dev)) 145 goto stall; 146 if (ep->dev->driver) { 147 EPDBG(ep, "forwarding to gadget...\n"); 148 spin_unlock(&ep->vhub->lock); 149 rc = ep->dev->driver->setup(&ep->dev->gadget, &crq); 150 spin_lock(&ep->vhub->lock); 151 EPDBG(ep, "driver returned %d\n", rc); 152 } else { 153 EPDBG(ep, "no gadget for request !\n"); 154 } 155 if (rc >= 0) 156 return; 157 158 stall: 159 EPDBG(ep, "stalling\n"); 160 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat); 161 ep->ep0.state = ep0_state_status; 162 ep->ep0.dir_in = false; 163 return; 164 165 complete: 166 EPVDBG(ep, "sending [in] status with no data\n"); 167 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat); 168 ep->ep0.state = ep0_state_status; 169 ep->ep0.dir_in = false; 170 } 171 172 173 static void ast_vhub_ep0_do_send(struct ast_vhub_ep *ep, 174 struct ast_vhub_req *req) 175 { 176 unsigned int chunk; 177 u32 reg; 178 179 /* If this is a 0-length request, it's the gadget trying to 180 * send a status on our behalf. We take it from here. 181 */ 182 if (req->req.length == 0) 183 req->last_desc = 1; 184 185 /* Are we done ? Complete request, otherwise wait for next interrupt */ 186 if (req->last_desc >= 0) { 187 EPVDBG(ep, "complete send %d/%d\n", 188 req->req.actual, req->req.length); 189 ep->ep0.state = ep0_state_status; 190 writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat); 191 ast_vhub_done(ep, req, 0); 192 return; 193 } 194 195 /* 196 * Next chunk cropped to max packet size. Also check if this 197 * is the last packet 198 */ 199 chunk = req->req.length - req->req.actual; 200 if (chunk > ep->ep.maxpacket) 201 chunk = ep->ep.maxpacket; 202 else if ((chunk < ep->ep.maxpacket) || !req->req.zero) 203 req->last_desc = 1; 204 205 EPVDBG(ep, "send chunk=%d last=%d, req->act=%d mp=%d\n", 206 chunk, req->last_desc, req->req.actual, ep->ep.maxpacket); 207 208 /* 209 * Copy data if any (internal requests already have data 210 * in the EP buffer) 211 */ 212 if (chunk && req->req.buf) 213 memcpy(ep->buf, req->req.buf + req->req.actual, chunk); 214 215 /* Remember chunk size and trigger send */ 216 reg = VHUB_EP0_SET_TX_LEN(chunk); 217 writel(reg, ep->ep0.ctlstat); 218 writel(reg | VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat); 219 req->req.actual += chunk; 220 } 221 222 static void ast_vhub_ep0_rx_prime(struct ast_vhub_ep *ep) 223 { 224 EPVDBG(ep, "rx prime\n"); 225 226 /* Prime endpoint for receiving data */ 227 writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat + AST_VHUB_EP0_CTRL); 228 } 229 230 static void ast_vhub_ep0_do_receive(struct ast_vhub_ep *ep, struct ast_vhub_req *req, 231 unsigned int len) 232 { 233 unsigned int remain; 234 int rc = 0; 235 236 /* We are receiving... grab request */ 237 remain = req->req.length - req->req.actual; 238 239 EPVDBG(ep, "receive got=%d remain=%d\n", len, remain); 240 241 /* Are we getting more than asked ? */ 242 if (len > remain) { 243 EPDBG(ep, "receiving too much (ovf: %d) !\n", 244 len - remain); 245 len = remain; 246 rc = -EOVERFLOW; 247 } 248 if (len && req->req.buf) 249 memcpy(req->req.buf + req->req.actual, ep->buf, len); 250 req->req.actual += len; 251 252 /* Done ? */ 253 if (len < ep->ep.maxpacket || len == remain) { 254 ep->ep0.state = ep0_state_status; 255 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat); 256 ast_vhub_done(ep, req, rc); 257 } else 258 ast_vhub_ep0_rx_prime(ep); 259 } 260 261 void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack) 262 { 263 struct ast_vhub_req *req; 264 struct ast_vhub *vhub = ep->vhub; 265 struct device *dev = &vhub->pdev->dev; 266 bool stall = false; 267 u32 stat; 268 269 /* Read EP0 status */ 270 stat = readl(ep->ep0.ctlstat); 271 272 /* Grab current request if any */ 273 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue); 274 275 EPVDBG(ep, "ACK status=%08x,state=%d is_in=%d in_ack=%d req=%p\n", 276 stat, ep->ep0.state, ep->ep0.dir_in, in_ack, req); 277 278 switch(ep->ep0.state) { 279 case ep0_state_token: 280 /* There should be no request queued in that state... */ 281 if (req) { 282 dev_warn(dev, "request present while in TOKEN state\n"); 283 ast_vhub_nuke(ep, -EINVAL); 284 } 285 dev_warn(dev, "ack while in TOKEN state\n"); 286 stall = true; 287 break; 288 case ep0_state_data: 289 /* Check the state bits corresponding to our direction */ 290 if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) || 291 (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) || 292 (ep->ep0.dir_in != in_ack)) { 293 dev_warn(dev, "irq state mismatch"); 294 stall = true; 295 break; 296 } 297 /* 298 * We are in data phase and there's no request, something is 299 * wrong, stall 300 */ 301 if (!req) { 302 dev_warn(dev, "data phase, no request\n"); 303 stall = true; 304 break; 305 } 306 307 /* We have a request, handle data transfers */ 308 if (ep->ep0.dir_in) 309 ast_vhub_ep0_do_send(ep, req); 310 else 311 ast_vhub_ep0_do_receive(ep, req, VHUB_EP0_RX_LEN(stat)); 312 return; 313 case ep0_state_status: 314 /* Nuke stale requests */ 315 if (req) { 316 dev_warn(dev, "request present while in STATUS state\n"); 317 ast_vhub_nuke(ep, -EINVAL); 318 } 319 320 /* 321 * If the status phase completes with the wrong ack, stall 322 * the endpoint just in case, to abort whatever the host 323 * was doing. 324 */ 325 if (ep->ep0.dir_in == in_ack) { 326 dev_warn(dev, "status direction mismatch\n"); 327 stall = true; 328 } 329 } 330 331 /* Reset to token state */ 332 ep->ep0.state = ep0_state_token; 333 if (stall) 334 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat); 335 } 336 337 static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req, 338 gfp_t gfp_flags) 339 { 340 struct ast_vhub_req *req = to_ast_req(u_req); 341 struct ast_vhub_ep *ep = to_ast_ep(u_ep); 342 struct ast_vhub *vhub = ep->vhub; 343 struct device *dev = &vhub->pdev->dev; 344 unsigned long flags; 345 346 /* Paranoid cheks */ 347 if (!u_req || (!u_req->complete && !req->internal)) { 348 dev_warn(dev, "Bogus EP0 request ! u_req=%p\n", u_req); 349 if (u_req) { 350 dev_warn(dev, "complete=%p internal=%d\n", 351 u_req->complete, req->internal); 352 } 353 return -EINVAL; 354 } 355 356 /* Not endpoint 0 ? */ 357 if (WARN_ON(ep->d_idx != 0)) 358 return -EINVAL; 359 360 /* Disabled device */ 361 if (ep->dev && (!ep->dev->enabled || ep->dev->suspended)) 362 return -ESHUTDOWN; 363 364 /* Data, no buffer and not internal ? */ 365 if (u_req->length && !u_req->buf && !req->internal) { 366 dev_warn(dev, "Request with no buffer !\n"); 367 return -EINVAL; 368 } 369 370 EPVDBG(ep, "enqueue req @%p\n", req); 371 EPVDBG(ep, " l=%d zero=%d noshort=%d is_in=%d\n", 372 u_req->length, u_req->zero, 373 u_req->short_not_ok, ep->ep0.dir_in); 374 375 /* Initialize request progress fields */ 376 u_req->status = -EINPROGRESS; 377 u_req->actual = 0; 378 req->last_desc = -1; 379 req->active = false; 380 381 spin_lock_irqsave(&vhub->lock, flags); 382 383 /* EP0 can only support a single request at a time */ 384 if (!list_empty(&ep->queue) || ep->ep0.state == ep0_state_token) { 385 dev_warn(dev, "EP0: Request in wrong state\n"); 386 spin_unlock_irqrestore(&vhub->lock, flags); 387 return -EBUSY; 388 } 389 390 /* Add request to list and kick processing if empty */ 391 list_add_tail(&req->queue, &ep->queue); 392 393 if (ep->ep0.dir_in) { 394 /* IN request, send data */ 395 ast_vhub_ep0_do_send(ep, req); 396 } else if (u_req->length == 0) { 397 /* 0-len request, send completion as rx */ 398 EPVDBG(ep, "0-length rx completion\n"); 399 ep->ep0.state = ep0_state_status; 400 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat); 401 ast_vhub_done(ep, req, 0); 402 } else { 403 /* OUT request, start receiver */ 404 ast_vhub_ep0_rx_prime(ep); 405 } 406 407 spin_unlock_irqrestore(&vhub->lock, flags); 408 409 return 0; 410 } 411 412 static int ast_vhub_ep0_dequeue(struct usb_ep* u_ep, struct usb_request *u_req) 413 { 414 struct ast_vhub_ep *ep = to_ast_ep(u_ep); 415 struct ast_vhub *vhub = ep->vhub; 416 struct ast_vhub_req *req; 417 unsigned long flags; 418 int rc = -EINVAL; 419 420 spin_lock_irqsave(&vhub->lock, flags); 421 422 /* Only one request can be in the queue */ 423 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue); 424 425 /* Is it ours ? */ 426 if (req && u_req == &req->req) { 427 EPVDBG(ep, "dequeue req @%p\n", req); 428 429 /* 430 * We don't have to deal with "active" as all 431 * DMAs go to the EP buffers, not the request. 432 */ 433 ast_vhub_done(ep, req, -ECONNRESET); 434 435 /* We do stall the EP to clean things up in HW */ 436 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat); 437 ep->ep0.state = ep0_state_status; 438 ep->ep0.dir_in = false; 439 rc = 0; 440 } 441 spin_unlock_irqrestore(&vhub->lock, flags); 442 return rc; 443 } 444 445 446 static const struct usb_ep_ops ast_vhub_ep0_ops = { 447 .queue = ast_vhub_ep0_queue, 448 .dequeue = ast_vhub_ep0_dequeue, 449 .alloc_request = ast_vhub_alloc_request, 450 .free_request = ast_vhub_free_request, 451 }; 452 453 void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep, 454 struct ast_vhub_dev *dev) 455 { 456 memset(ep, 0, sizeof(*ep)); 457 458 INIT_LIST_HEAD(&ep->ep.ep_list); 459 INIT_LIST_HEAD(&ep->queue); 460 ep->ep.ops = &ast_vhub_ep0_ops; 461 ep->ep.name = "ep0"; 462 ep->ep.caps.type_control = true; 463 usb_ep_set_maxpacket_limit(&ep->ep, AST_VHUB_EP0_MAX_PACKET); 464 ep->d_idx = 0; 465 ep->dev = dev; 466 ep->vhub = vhub; 467 ep->ep0.state = ep0_state_token; 468 INIT_LIST_HEAD(&ep->ep0.req.queue); 469 ep->ep0.req.internal = true; 470 471 /* Small difference between vHub and devices */ 472 if (dev) { 473 ep->ep0.ctlstat = dev->regs + AST_VHUB_DEV_EP0_CTRL; 474 ep->ep0.setup = vhub->regs + 475 AST_VHUB_SETUP0 + 8 * (dev->index + 1); 476 ep->buf = vhub->ep0_bufs + 477 AST_VHUB_EP0_MAX_PACKET * (dev->index + 1); 478 ep->buf_dma = vhub->ep0_bufs_dma + 479 AST_VHUB_EP0_MAX_PACKET * (dev->index + 1); 480 } else { 481 ep->ep0.ctlstat = vhub->regs + AST_VHUB_EP0_CTRL; 482 ep->ep0.setup = vhub->regs + AST_VHUB_SETUP0; 483 ep->buf = vhub->ep0_bufs; 484 ep->buf_dma = vhub->ep0_bufs_dma; 485 } 486 } 487