^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * usb.c - Hardware dependent module for USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/most.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define USB_MTU 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define NO_ISOCHRONOUS_URB 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AV_PACKETS_PER_XACT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define BUF_CHAIN_SIZE 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX_NUM_ENDPOINTS 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX_SUFFIX_LEN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MAX_STRING_LEN 80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MAX_BUF_SIZE 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define USB_VENDOR_ID_SMSC 0x0424 /* VID: SMSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define USB_DEV_ID_BRDG 0xC001 /* PID: USB Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define USB_DEV_ID_OS81118 0xCF18 /* PID: USB OS81118 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define USB_DEV_ID_OS81119 0xCF19 /* PID: USB OS81119 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define USB_DEV_ID_OS81210 0xCF30 /* PID: USB OS81210 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* DRCI Addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DRCI_REG_NI_STATE 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DRCI_REG_PACKET_BW 0x0101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DRCI_REG_NODE_ADDR 0x0102
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DRCI_REG_NODE_POS 0x0103
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DRCI_REG_MEP_FILTER 0x0140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DRCI_REG_HASH_TBL0 0x0141
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DRCI_REG_HASH_TBL1 0x0142
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DRCI_REG_HASH_TBL2 0x0143
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DRCI_REG_HASH_TBL3 0x0144
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DRCI_REG_HW_ADDR_HI 0x0145
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DRCI_REG_HW_ADDR_MI 0x0146
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DRCI_REG_HW_ADDR_LO 0x0147
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DRCI_REG_BASE 0x1100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DRCI_COMMAND 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DRCI_READ_REQ 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DRCI_WRITE_REQ 0xA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * struct most_dci_obj - Direct Communication Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @kobj:position in sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @usb_device: pointer to the usb device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @reg_addr: register address for arbitrary DCI access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct most_dci_obj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct usb_device *usb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u16 reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define to_dci_obj(p) container_of(p, struct most_dci_obj, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct most_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct clear_hold_work {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct work_struct ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct most_dev *mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define to_clear_hold_work(w) container_of(w, struct clear_hold_work, ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * struct most_dev - holds all usb interface specific stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @usb_device: pointer to usb device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @iface: hardware interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @cap: channel capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @conf: channel configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @dci: direct communication interface of hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @ep_address: endpoint address table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @description: device description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @suffix: suffix for channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @channel_lock: synchronize channel access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @padding_active: indicates channel uses padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @is_channel_healthy: health status table of each channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @busy_urbs: list of anchored items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @io_mutex: synchronize I/O with disconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @link_stat_timer: timer for link status reports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @poll_work_obj: work for polling link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct most_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct usb_device *usb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct most_interface iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct most_channel_capability *cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct most_channel_config *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct most_dci_obj *dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u8 *ep_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) char description[MAX_STRING_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) char suffix[MAX_NUM_ENDPOINTS][MAX_SUFFIX_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) spinlock_t channel_lock[MAX_NUM_ENDPOINTS]; /* sync channel access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bool padding_active[MAX_NUM_ENDPOINTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bool is_channel_healthy[MAX_NUM_ENDPOINTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct clear_hold_work clear_work[MAX_NUM_ENDPOINTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct usb_anchor *busy_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct mutex io_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct timer_list link_stat_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct work_struct poll_work_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void (*on_netinfo)(struct most_interface *most_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned char link_state, unsigned char *addrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define to_mdev(d) container_of(d, struct most_dev, iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define to_mdev_from_dev(d) container_of(d, struct most_dev, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define to_mdev_from_work(w) container_of(w, struct most_dev, poll_work_obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void wq_clear_halt(struct work_struct *wq_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void wq_netinfo(struct work_struct *wq_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * drci_rd_reg - read a DCI register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @dev: usb device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @reg: register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @buf: buffer to store data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * This is reads data from INIC's direct register communication interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __le16 *dma_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u8 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!dma_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) DRCI_READ_REQ, req_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) reg, dma_buf, sizeof(*dma_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) USB_CTRL_GET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *buf = le16_to_cpu(*dma_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kfree(dma_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * drci_wr_reg - write a DCI register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @dev: usb device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @reg: register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @data: data to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * This is writes data to INIC's direct register communication interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static inline int drci_wr_reg(struct usb_device *dev, u16 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) DRCI_WRITE_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static inline int start_sync_ep(struct usb_device *usb_dev, u16 ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return drci_wr_reg(usb_dev, DRCI_REG_BASE + DRCI_COMMAND + ep * 16, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * get_stream_frame_size - calculate frame size of current configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @dev: device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @cfg: channel configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static unsigned int get_stream_frame_size(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct most_channel_config *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned int frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned int sub_size = cfg->subbuffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (!sub_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev_warn(dev, "Misconfig: Subbuffer size zero.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (cfg->data_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case MOST_CH_ISOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) frame_size = AV_PACKETS_PER_XACT * sub_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case MOST_CH_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (cfg->packets_per_xact == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_warn(dev, "Misconfig: Packets per XACT zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) frame_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) } else if (cfg->packets_per_xact == 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) frame_size = (USB_MTU / sub_size) * sub_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) frame_size = cfg->packets_per_xact * sub_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_warn(dev, "Query frame size of non-streaming channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) frame_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * hdm_poison_channel - mark buffers of this channel as invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @iface: pointer to the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @channel: channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * This unlinks all URBs submitted to the HCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * calls the associated completion function of the core and removes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * them from the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Returns 0 on success or error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int hdm_poison_channel(struct most_interface *iface, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct most_dev *mdev = to_mdev(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) spinlock_t *lock; /* temp. lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (channel < 0 || channel >= iface->num_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev_warn(&mdev->usb_device->dev, "Channel ID out of range.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -ECHRNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) lock = mdev->channel_lock + channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) spin_lock_irqsave(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mdev->is_channel_healthy[channel] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cancel_work_sync(&mdev->clear_work[channel].ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) usb_kill_anchored_urbs(&mdev->busy_urbs[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (mdev->padding_active[channel])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mdev->padding_active[channel] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (mdev->conf[channel].data_type == MOST_CH_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) del_timer_sync(&mdev->link_stat_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) cancel_work_sync(&mdev->poll_work_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * hdm_add_padding - add padding bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @mdev: most device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @channel: channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @mbo: buffer object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * This inserts the INIC hardware specific padding bytes into a streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * channel's buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct most_channel_config *conf = &mdev->conf[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned int frame_size = get_stream_frame_size(&mdev->dev, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int j, num_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) num_frames = mbo->buffer_length / frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (num_frames < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_err(&mdev->usb_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "Missed minimal transfer unit.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) for (j = num_frames - 1; j > 0; j--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) memmove(mbo->virt_address + j * USB_MTU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mbo->virt_address + j * frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) mbo->buffer_length = num_frames * USB_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * hdm_remove_padding - remove padding bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @mdev: most device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @channel: channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @mbo: buffer object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * This takes the INIC hardware specific padding bytes off a streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * channel's buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static int hdm_remove_padding(struct most_dev *mdev, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct mbo *mbo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct most_channel_config *const conf = &mdev->conf[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned int frame_size = get_stream_frame_size(&mdev->dev, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int j, num_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) num_frames = mbo->processed_length / USB_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (j = 1; j < num_frames; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) memmove(mbo->virt_address + frame_size * j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) mbo->virt_address + USB_MTU * j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) mbo->processed_length = frame_size * num_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * hdm_write_completion - completion function for submitted Tx URBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * @urb: the URB that has been completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * This checks the status of the completed URB. In case the URB has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * unlinked before, it is immediately freed. On any other error the MBO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * transfer flag is set. On success it frees allocated resources and calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * the completion function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Context: interrupt!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static void hdm_write_completion(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct mbo *mbo = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct most_dev *mdev = to_mdev(mbo->ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) unsigned int channel = mbo->hdm_channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) spinlock_t *lock = mdev->channel_lock + channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) spin_lock_irqsave(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mbo->processed_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mbo->status = MBO_E_INVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (likely(mdev->is_channel_healthy[channel])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mbo->processed_length = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) mbo->status = MBO_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case -EPIPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev_warn(&mdev->usb_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "Broken pipe on ep%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mdev->ep_address[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mdev->is_channel_healthy[channel] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mdev->clear_work[channel].pipe = urb->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) schedule_work(&mdev->clear_work[channel].ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case -EPROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mbo->status = MBO_E_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (likely(mbo->complete))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) mbo->complete(mbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * hdm_read_completion - completion function for submitted Rx URBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * @urb: the URB that has been completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * This checks the status of the completed URB. In case the URB has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * unlinked before it is immediately freed. On any other error the MBO transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * flag is set. On success it frees allocated resources, removes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * padding bytes -if necessary- and calls the completion function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Context: interrupt!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static void hdm_read_completion(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct mbo *mbo = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct most_dev *mdev = to_mdev(mbo->ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) unsigned int channel = mbo->hdm_channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct device *dev = &mdev->usb_device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) spinlock_t *lock = mdev->channel_lock + channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) spin_lock_irqsave(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mbo->processed_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mbo->status = MBO_E_INVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (likely(mdev->is_channel_healthy[channel])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) mbo->processed_length = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) mbo->status = MBO_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (mdev->padding_active[channel] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) hdm_remove_padding(mdev, channel, mbo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) mbo->processed_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mbo->status = MBO_E_INVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case -EPIPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dev_warn(dev, "Broken pipe on ep%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mdev->ep_address[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mdev->is_channel_healthy[channel] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) mdev->clear_work[channel].pipe = urb->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) schedule_work(&mdev->clear_work[channel].ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case -EPROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) mbo->status = MBO_E_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case -EOVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev_warn(dev, "Babble on ep%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mdev->ep_address[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (likely(mbo->complete))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) mbo->complete(mbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * hdm_enqueue - receive a buffer to be used for data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * @iface: interface to enqueue to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * @channel: ID of the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * @mbo: pointer to the buffer object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * This allocates a new URB and fills it according to the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * that is being used for transmission of data. Before the URB is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * submitted it is stored in the private anchor list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Returns 0 on success. On any error the URB is freed and a error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * Context: Could in _some_ cases be interrupt!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int hdm_enqueue(struct most_interface *iface, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct mbo *mbo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct most_dev *mdev = to_mdev(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct most_channel_config *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) unsigned long length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) void *virt_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!mbo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (iface->num_channels <= channel || channel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -ECHRNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) urb = usb_alloc_urb(NO_ISOCHRONOUS_URB, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) conf = &mdev->conf[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!mdev->usb_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) goto err_free_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) hdm_add_padding(mdev, channel, mbo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto err_free_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) urb->transfer_dma = mbo->bus_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) virt_address = mbo->virt_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) length = mbo->buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (conf->direction & MOST_CH_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) usb_fill_bulk_urb(urb, mdev->usb_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) usb_sndbulkpipe(mdev->usb_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mdev->ep_address[channel]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) virt_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) hdm_write_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (conf->data_type != MOST_CH_ISOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) conf->data_type != MOST_CH_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) urb->transfer_flags |= URB_ZERO_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) usb_fill_bulk_urb(urb, mdev->usb_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) usb_rcvbulkpipe(mdev->usb_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mdev->ep_address[channel]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) virt_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) length + conf->extra_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) hdm_read_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mbo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) usb_anchor_urb(urb, &mdev->busy_urbs[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) retval = usb_submit_urb(urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dev_err(&mdev->usb_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) "URB submit failed with error %d.\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) goto err_unanchor_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) err_unanchor_urb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) usb_unanchor_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) err_free_urb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static void *hdm_dma_alloc(struct mbo *mbo, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct most_dev *mdev = to_mdev(mbo->ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return usb_alloc_coherent(mdev->usb_device, size, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) &mbo->bus_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static void hdm_dma_free(struct mbo *mbo, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct most_dev *mdev = to_mdev(mbo->ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) usb_free_coherent(mdev->usb_device, size, mbo->virt_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mbo->bus_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * hdm_configure_channel - receive channel configuration from core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * @iface: interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * @channel: channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * @conf: structure that holds the configuration information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * The attached network interface controller (NIC) supports a padding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * to avoid short packets on USB, hence increasing the performance due to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * lower interrupt load. This mode is default for synchronous data and can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * be switched on for isochronous data. In case padding is active the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * driver needs to know the frame size of the payload in order to calculate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * the number of bytes it needs to pad when transmitting or to cut off when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * receiving data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int hdm_configure_channel(struct most_interface *iface, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct most_channel_config *conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned int num_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) unsigned int frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct most_dev *mdev = to_mdev(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct device *dev = &mdev->usb_device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (!conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) dev_err(dev, "Bad config pointer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (channel < 0 || channel >= iface->num_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dev_err(dev, "Channel ID out of range.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) mdev->is_channel_healthy[channel] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mdev->clear_work[channel].channel = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) mdev->clear_work[channel].mdev = mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) INIT_WORK(&mdev->clear_work[channel].ws, wq_clear_halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (!conf->num_buffers || !conf->buffer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) dev_err(dev, "Misconfig: buffer size or #buffers zero.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (conf->data_type != MOST_CH_SYNC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) !(conf->data_type == MOST_CH_ISOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) conf->packets_per_xact != 0xFF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mdev->padding_active[channel] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * Since the NIC's padding mode is not going to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * used, we can skip the frame size calculations and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * move directly on to exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mdev->padding_active[channel] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) frame_size = get_stream_frame_size(&mdev->dev, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (frame_size == 0 || frame_size > USB_MTU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dev_warn(dev, "Misconfig: frame size wrong\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) num_frames = conf->buffer_size / frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (conf->buffer_size % frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) u16 old_size = conf->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) conf->buffer_size = num_frames * frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dev_warn(dev, "%s: fixed buffer size (%d -> %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) mdev->suffix[channel], old_size, conf->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* calculate extra length to comply w/ HW padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) conf->extra_len = num_frames * (USB_MTU - frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mdev->conf[channel] = *conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (conf->data_type == MOST_CH_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) u16 ep = mdev->ep_address[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (start_sync_ep(mdev->usb_device, ep) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dev_warn(dev, "sync for ep%02x failed", ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * hdm_request_netinfo - request network information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * @iface: pointer to interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * @channel: channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * This is used as trigger to set up the link status timer that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * polls for the NI state of the INIC every 2 seconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static void hdm_request_netinfo(struct most_interface *iface, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) void (*on_netinfo)(struct most_interface *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) unsigned char *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct most_dev *mdev = to_mdev(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) mdev->on_netinfo = on_netinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (!on_netinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) mdev->link_stat_timer.expires = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) mod_timer(&mdev->link_stat_timer, mdev->link_stat_timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * link_stat_timer_handler - schedule work obtaining mac address and link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * @data: pointer to USB device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * The handler runs in interrupt context. That's why we need to defer the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * tasks to a work queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static void link_stat_timer_handler(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct most_dev *mdev = from_timer(mdev, t, link_stat_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) schedule_work(&mdev->poll_work_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) mdev->link_stat_timer.expires = jiffies + (2 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) add_timer(&mdev->link_stat_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * wq_netinfo - work queue function to deliver latest networking information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * @wq_obj: object that holds data for our deferred work to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * This retrieves the network interface status of the USB INIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static void wq_netinfo(struct work_struct *wq_obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct most_dev *mdev = to_mdev_from_work(wq_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct usb_device *usb_device = mdev->usb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct device *dev = &usb_device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) u16 hi, mi, lo, link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u8 hw_addr[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_HI, &hi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dev_err(dev, "Vendor request 'hw_addr_hi' failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_MI, &mi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) dev_err(dev, "Vendor request 'hw_addr_mid' failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_LO, &lo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) dev_err(dev, "Vendor request 'hw_addr_low' failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (drci_rd_reg(usb_device, DRCI_REG_NI_STATE, &link)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dev_err(dev, "Vendor request 'link status' failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) hw_addr[0] = hi >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) hw_addr[1] = hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) hw_addr[2] = mi >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) hw_addr[3] = mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hw_addr[4] = lo >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) hw_addr[5] = lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (mdev->on_netinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) mdev->on_netinfo(&mdev->iface, link, hw_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * wq_clear_halt - work queue function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * @wq_obj: work_struct object to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * This sends a clear_halt to the given USB pipe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static void wq_clear_halt(struct work_struct *wq_obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct clear_hold_work *clear_work = to_clear_hold_work(wq_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct most_dev *mdev = clear_work->mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) unsigned int channel = clear_work->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) int pipe = clear_work->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int snd_pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) int peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) most_stop_enqueue(&mdev->iface, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) usb_kill_anchored_urbs(&mdev->busy_urbs[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (usb_clear_halt(mdev->usb_device, pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) dev_warn(&mdev->usb_device->dev, "Failed to reset endpoint.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* If the functional Stall condition has been set on an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * asynchronous rx channel, we need to clear the tx channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * too, since the hardware runs its clean-up sequence on both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * channels, as they are physically one on the network.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * The USB interface that exposes the asynchronous channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * contains always two endpoints, and two only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (mdev->conf[channel].data_type == MOST_CH_ASYNC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) mdev->conf[channel].direction == MOST_CH_RX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (channel == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) peer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) peer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) snd_pipe = usb_sndbulkpipe(mdev->usb_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) mdev->ep_address[peer]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) usb_clear_halt(mdev->usb_device, snd_pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mdev->is_channel_healthy[channel] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) most_resume_enqueue(&mdev->iface, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * hdm_usb_fops - file operation table for USB driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static const struct file_operations hdm_usb_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * usb_device_id - ID table for HCD device probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static const struct usb_device_id usbid[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81118), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81210), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static const struct regs ro_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) { "ni_state", DRCI_REG_NI_STATE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) { "packet_bandwidth", DRCI_REG_PACKET_BW },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) { "node_address", DRCI_REG_NODE_ADDR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { "node_position", DRCI_REG_NODE_POS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static const struct regs rw_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) { "mep_filter", DRCI_REG_MEP_FILTER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) { "mep_hash0", DRCI_REG_HASH_TBL0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) { "mep_hash1", DRCI_REG_HASH_TBL1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) { "mep_hash2", DRCI_REG_HASH_TBL2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) { "mep_hash3", DRCI_REG_HASH_TBL3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) { "mep_eui48_hi", DRCI_REG_HW_ADDR_HI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) { "mep_eui48_mi", DRCI_REG_HW_ADDR_MI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) { "mep_eui48_lo", DRCI_REG_HW_ADDR_LO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static int get_stat_reg_addr(const struct regs *regs, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) const char *name, u16 *reg_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (sysfs_streq(name, regs[i].name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) *reg_addr = regs[i].reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #define get_static_reg_addr(regs, name, reg_addr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) get_stat_reg_addr(regs, ARRAY_SIZE(regs), name, reg_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static ssize_t value_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) const char *name = attr->attr.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct most_dci_obj *dci_obj = to_dci_obj(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) u16 reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (sysfs_streq(name, "arb_address"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return snprintf(buf, PAGE_SIZE, "%04x\n", dci_obj->reg_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (sysfs_streq(name, "arb_value"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) reg_addr = dci_obj->reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) else if (get_static_reg_addr(ro_regs, name, ®_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) get_static_reg_addr(rw_regs, name, ®_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) err = drci_rd_reg(dci_obj->usb_device, reg_addr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return snprintf(buf, PAGE_SIZE, "%04x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static ssize_t value_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) u16 reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) const char *name = attr->attr.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct most_dci_obj *dci_obj = to_dci_obj(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct usb_device *usb_dev = dci_obj->usb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) err = kstrtou16(buf, 16, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (sysfs_streq(name, "arb_address")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dci_obj->reg_addr = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (sysfs_streq(name, "arb_value"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) err = drci_wr_reg(usb_dev, dci_obj->reg_addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) else if (sysfs_streq(name, "sync_ep"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) err = start_sync_ep(usb_dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) else if (!get_static_reg_addr(rw_regs, name, ®_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) err = drci_wr_reg(usb_dev, reg_addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static DEVICE_ATTR(ni_state, 0444, value_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static DEVICE_ATTR(packet_bandwidth, 0444, value_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static DEVICE_ATTR(node_address, 0444, value_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static DEVICE_ATTR(node_position, 0444, value_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static DEVICE_ATTR(sync_ep, 0200, NULL, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static DEVICE_ATTR(mep_filter, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static DEVICE_ATTR(mep_hash0, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static DEVICE_ATTR(mep_hash1, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static DEVICE_ATTR(mep_hash2, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static DEVICE_ATTR(mep_hash3, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static DEVICE_ATTR(mep_eui48_hi, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static DEVICE_ATTR(mep_eui48_mi, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static DEVICE_ATTR(mep_eui48_lo, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static DEVICE_ATTR(arb_address, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static DEVICE_ATTR(arb_value, 0644, value_show, value_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static struct attribute *dci_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) &dev_attr_ni_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) &dev_attr_packet_bandwidth.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) &dev_attr_node_address.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) &dev_attr_node_position.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) &dev_attr_sync_ep.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) &dev_attr_mep_filter.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) &dev_attr_mep_hash0.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) &dev_attr_mep_hash1.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) &dev_attr_mep_hash2.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) &dev_attr_mep_hash3.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) &dev_attr_mep_eui48_hi.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) &dev_attr_mep_eui48_mi.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) &dev_attr_mep_eui48_lo.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) &dev_attr_arb_address.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) &dev_attr_arb_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ATTRIBUTE_GROUPS(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static void release_dci(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct most_dci_obj *dci = to_dci_obj(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) put_device(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) kfree(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static void release_mdev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct most_dev *mdev = to_mdev_from_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) kfree(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * hdm_probe - probe function of USB device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * @interface: Interface of the attached USB device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * @id: Pointer to the USB ID table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * This allocates and initializes the device instance, adds the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * entry to the internal list, scans the USB descriptors and registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * the interface with the core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * Additionally, the DCI objects are created and the hardware is sync'd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Return 0 on success. In case of an error a negative number is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct usb_host_interface *usb_iface_desc = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct usb_device *usb_dev = interface_to_usbdev(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct device *dev = &usb_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct most_dev *mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) unsigned int num_endpoints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct most_channel_capability *tmp_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct usb_endpoint_descriptor *ep_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) usb_set_intfdata(interface, mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) num_endpoints = usb_iface_desc->desc.bNumEndpoints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (num_endpoints > MAX_NUM_ENDPOINTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) kfree(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) mutex_init(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) INIT_WORK(&mdev->poll_work_obj, wq_netinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) timer_setup(&mdev->link_stat_timer, link_stat_timer_handler, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) mdev->usb_device = usb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) mdev->link_stat_timer.expires = jiffies + (2 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) mdev->iface.mod = hdm_usb_fops.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) mdev->iface.dev = &mdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) mdev->iface.driver_dev = &interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) mdev->iface.interface = ITYPE_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) mdev->iface.configure = hdm_configure_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mdev->iface.request_netinfo = hdm_request_netinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) mdev->iface.enqueue = hdm_enqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) mdev->iface.poison_channel = hdm_poison_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) mdev->iface.dma_alloc = hdm_dma_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) mdev->iface.dma_free = hdm_dma_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) mdev->iface.description = mdev->description;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) mdev->iface.num_channels = num_endpoints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) snprintf(mdev->description, sizeof(mdev->description),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) "%d-%s:%d.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) usb_dev->bus->busnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) usb_dev->devpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) usb_dev->config->desc.bConfigurationValue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) usb_iface_desc->desc.bInterfaceNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) mdev->dev.init_name = mdev->description;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mdev->dev.parent = &interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mdev->dev.release = release_mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (!mdev->conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) goto err_free_mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (!mdev->cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto err_free_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) mdev->iface.channel_vector = mdev->cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) mdev->ep_address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!mdev->ep_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) goto err_free_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) mdev->busy_urbs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!mdev->busy_urbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) goto err_free_ep_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) tmp_cap = mdev->cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) for (i = 0; i < num_endpoints; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ep_desc = &usb_iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mdev->ep_address[i] = ep_desc->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) mdev->padding_active[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mdev->is_channel_healthy[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) snprintf(&mdev->suffix[i][0], MAX_SUFFIX_LEN, "ep%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) mdev->ep_address[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) tmp_cap->name_suffix = &mdev->suffix[i][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) tmp_cap->buffer_size_packet = MAX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) tmp_cap->buffer_size_streaming = MAX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) tmp_cap->num_buffers_packet = BUF_CHAIN_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) tmp_cap->num_buffers_streaming = BUF_CHAIN_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) tmp_cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) MOST_CH_ISOC | MOST_CH_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (usb_endpoint_dir_in(ep_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) tmp_cap->direction = MOST_CH_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) tmp_cap->direction = MOST_CH_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) tmp_cap++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) init_usb_anchor(&mdev->busy_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) spin_lock_init(&mdev->channel_lock[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) dev_dbg(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) le16_to_cpu(usb_dev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) le16_to_cpu(usb_dev->descriptor.idProduct),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) usb_dev->bus->busnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) usb_dev->devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) dev_dbg(dev, "device path: /sys/bus/usb/devices/%d-%s:%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) usb_dev->bus->busnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) usb_dev->devpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) usb_dev->config->desc.bConfigurationValue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) usb_iface_desc->desc.bInterfaceNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) ret = most_register_interface(&mdev->iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) goto err_free_busy_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!mdev->dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) most_deregister_interface(&mdev->iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) goto err_free_busy_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) mdev->dci->dev.init_name = "dci";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) mdev->dci->dev.parent = get_device(mdev->iface.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) mdev->dci->dev.groups = dci_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) mdev->dci->dev.release = release_dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (device_register(&mdev->dci->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) most_deregister_interface(&mdev->iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) goto err_free_dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) mdev->dci->usb_device = mdev->usb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) err_free_dci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) put_device(&mdev->dci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) err_free_busy_urbs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) kfree(mdev->busy_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) err_free_ep_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) kfree(mdev->ep_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) err_free_cap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) kfree(mdev->cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) err_free_conf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) kfree(mdev->conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) err_free_mdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) put_device(&mdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * hdm_disconnect - disconnect function of USB device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * @interface: Interface of the attached USB device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * This deregisters the interface with the core, removes the kernel timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * and frees resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * Context: hub kernel thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void hdm_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct most_dev *mdev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) mdev->usb_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) del_timer_sync(&mdev->link_stat_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) cancel_work_sync(&mdev->poll_work_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (mdev->dci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) device_unregister(&mdev->dci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) most_deregister_interface(&mdev->iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) kfree(mdev->busy_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) kfree(mdev->cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) kfree(mdev->conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) kfree(mdev->ep_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) put_device(&mdev->dci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) put_device(&mdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static int hdm_suspend(struct usb_interface *interface, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct most_dev *mdev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) for (i = 0; i < mdev->iface.num_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) most_stop_enqueue(&mdev->iface, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) usb_kill_anchored_urbs(&mdev->busy_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static int hdm_resume(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct most_dev *mdev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) mutex_lock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) for (i = 0; i < mdev->iface.num_channels; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) most_resume_enqueue(&mdev->iface, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mutex_unlock(&mdev->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static struct usb_driver hdm_usb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) .name = "hdm_usb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) .id_table = usbid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) .probe = hdm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .disconnect = hdm_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .resume = hdm_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .suspend = hdm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) module_usb_driver(hdm_usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) MODULE_DESCRIPTION("HDM_4_USB");