if (!urb)
return -ENOMEM;
+ gbuf->hcd_data = urb;
+
usb_fill_bulk_urb(urb, udev,
usb_sndbulkpipe(udev, es1->cport_out_endpoint),
buffer, gbuf->transfer_buffer_length + 1,
return retval;
}
+static int abort_gbuf(struct gbuf *gbuf)
+{
+ struct urb *urb = gbuf->hcd_data;
+
+ if (!urb)
+ return -EINVAL;
+
+ usb_kill_urb(urb);
+ return 0;
+}
+
static struct greybus_host_driver es1_driver = {
.hd_priv_size = sizeof(struct es1_ap_dev),
.alloc_gbuf_data = alloc_gbuf_data,
.free_gbuf_data = free_gbuf_data,
.submit_svc = submit_svc,
.submit_gbuf = submit_gbuf,
+ .abort_gbuf = abort_gbuf,
};
/* Common function to report consistent warnings based on URB status */
/* Record whether the transfer was successful */
gbuf->status = check_urb_status(urb);
+ gbuf->hcd_data = NULL;
/*
* See if this was an urb in our pool, if so mark it "free", otherwise
int greybus_kill_gbuf(struct gbuf *gbuf)
{
- // FIXME - implement
- return -ENOMEM;
+ struct greybus_host_device *hd = gbuf->connection->hd;
+
+ if (gbuf->status != -EINPROGRESS)
+ return -EINVAL;
+
+ return hd->driver->abort_gbuf(gbuf);
}
#define MAX_CPORTS 1024
bool outbound; /* AP-relative data direction */
void *context;
+ void *hcd_data; /* for the HCD to track the gbuf */
gbuf_complete_t complete;
};
int (*submit_svc)(struct svc_msg *svc_msg,
struct greybus_host_device *hd);
int (*submit_gbuf)(struct gbuf *gbuf, gfp_t gfp_mask);
+ int (*abort_gbuf)(struct gbuf *gbuf);
};
struct greybus_host_device {