diff options
Diffstat (limited to 'drivers/staging/r8188eu/hal/usb_ops_linux.c')
-rw-r--r-- | drivers/staging/r8188eu/hal/usb_ops_linux.c | 256 |
1 files changed, 122 insertions, 134 deletions
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c index 0cf69033c529..e4a9350376bf 100644 --- a/drivers/staging/r8188eu/hal/usb_ops_linux.c +++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c @@ -8,159 +8,179 @@ #include "../include/recv_osdep.h" #include "../include/rtl8188e_hal.h" -static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata, u16 len, u8 requesttype) +static int usb_read(struct intf_hdl *intf, u16 value, void *data, u8 size) { - struct adapter *adapt = pintfhdl->padapter; - struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt); + struct adapter *adapt = intf->padapter; + struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt); struct usb_device *udev = dvobjpriv->pusbdev; - unsigned int pipe; - int status = 0; - u8 *pIo_buf; - int vendorreq_times = 0; - - if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) { - status = -EPERM; - goto exit; + int status; + u8 io_buf[4]; + + if (adapt->bSurpriseRemoved || adapt->pwrctrlpriv.pnp_bstop_trx) + return -EPERM; + + status = usb_control_msg_recv(udev, 0, REALTEK_USB_VENQT_CMD_REQ, + REALTEK_USB_VENQT_READ, value, + REALTEK_USB_VENQT_CMD_IDX, io_buf, + size, RTW_USB_CONTROL_MSG_TIMEOUT, + GFP_KERNEL); + + if (status == -ESHUTDOWN || + status == -ENODEV || + status == -ENOENT) { + /* + * device or controller has been disabled due to + * some problem that could not be worked around, + * device or bus doesn’t exist, endpoint does not + * exist or is not enabled. + */ + adapt->bSurpriseRemoved = true; + return status; } - if (len > MAX_VENDOR_REQ_CMD_SIZE) { - DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__); - status = -EINVAL; - goto exit; + if (status < 0) { + if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) + adapt->bSurpriseRemoved = true; + + return status; } - _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); + rtw_reset_continual_urb_error(dvobjpriv); + memcpy(data, io_buf, size); - /* Acquire IO memory for vendorreq */ - pIo_buf = dvobjpriv->usb_vendor_req_buf; + return status; +} - if (!pIo_buf) { - DBG_88E("[%s] pIo_buf == NULL\n", __func__); - status = -ENOMEM; - goto release_mutex; +static int usb_write(struct intf_hdl *intf, u16 value, void *data, u8 size) +{ + struct adapter *adapt = intf->padapter; + struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt); + struct usb_device *udev = dvobjpriv->pusbdev; + int status; + u8 io_buf[VENDOR_CMD_MAX_DATA_LEN]; + + if (adapt->bSurpriseRemoved || adapt->pwrctrlpriv.pnp_bstop_trx) + return -EPERM; + + memcpy(io_buf, data, size); + status = usb_control_msg_send(udev, 0, REALTEK_USB_VENQT_CMD_REQ, + REALTEK_USB_VENQT_WRITE, value, + REALTEK_USB_VENQT_CMD_IDX, io_buf, + size, RTW_USB_CONTROL_MSG_TIMEOUT, + GFP_KERNEL); + + if (status == -ESHUTDOWN || + status == -ENODEV || + status == -ENOENT) { + /* + * device or controller has been disabled due to + * some problem that could not be worked around, + * device or bus doesn’t exist, endpoint does not + * exist or is not enabled. + */ + adapt->bSurpriseRemoved = true; + return status; } - if (requesttype == REALTEK_USB_VENQT_READ) - pipe = usb_rcvctrlpipe(udev, 0);/* read_in */ - else - pipe = usb_sndctrlpipe(udev, 0);/* write_out */ - - while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) { - if (requesttype == REALTEK_USB_VENQT_READ) - memset(pIo_buf, 0, len); - else - memcpy(pIo_buf, pdata, len); - - status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ, - requesttype, value, REALTEK_USB_VENQT_CMD_IDX, - pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); - - if (status == len) { /* Success this control transfer. */ - rtw_reset_continual_urb_error(dvobjpriv); - if (requesttype == REALTEK_USB_VENQT_READ) - memcpy(pdata, pIo_buf, len); - } else { /* error cases */ - DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n", - value, (requesttype == REALTEK_USB_VENQT_READ) ? "read" : "write", - len, status, *(u32 *)pdata, vendorreq_times); - - if (status < 0) { - if (status == (-ESHUTDOWN) || status == -ENODEV) { - adapt->bSurpriseRemoved = true; - } else { - struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); - haldata->srestpriv.wifi_error_status = USB_VEN_REQ_CMD_FAIL; - } - } else { /* status != len && status >= 0 */ - if (status > 0) { - if (requesttype == REALTEK_USB_VENQT_READ) { - /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */ - memcpy(pdata, pIo_buf, len); - } - } - } + if (status < 0) { + if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) + adapt->bSurpriseRemoved = true; - if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) { - adapt->bSurpriseRemoved = true; - break; - } + return status; + } - } + rtw_reset_continual_urb_error(dvobjpriv); - /* firmware download is checksumed, don't retry */ - if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len) - break; - } -release_mutex: - _exit_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); -exit: return status; } -static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) +u8 rtw_read8(struct adapter *adapter, u32 addr) { - u16 wvalue = (u16)(addr & 0x0000ffff); + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; u8 data; - usbctrl_vendorreq(pintfhdl, wvalue, &data, 1, REALTEK_USB_VENQT_READ); + usb_read(intf, value, &data, 1); return data; } -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) +u16 rtw_read16(struct adapter *adapter, u32 addr) { - u16 wvalue = (u16)(addr & 0x0000ffff); - __le32 data; + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; + __le16 data; - usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_READ); + usb_read(intf, value, &data, 2); - return (u16)(le32_to_cpu(data) & 0xffff); + return le16_to_cpu(data); } -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) +u32 rtw_read32(struct adapter *adapter, u32 addr) { - u16 wvalue = (u16)(addr & 0x0000ffff); + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; __le32 data; - usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_READ); + usb_read(intf, value, &data, 4); return le32_to_cpu(data); } -static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +int rtw_write8(struct adapter *adapter, u32 addr, u8 val) { - u16 wvalue = (u16)(addr & 0x0000ffff); + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; + int ret; - return usbctrl_vendorreq(pintfhdl, wvalue, &val, 1, REALTEK_USB_VENQT_WRITE); + ret = usb_write(intf, value, &val, 1); + + return RTW_STATUS_CODE(ret); } -static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +int rtw_write16(struct adapter *adapter, u32 addr, u16 val) { - u16 wvalue = (u16)(addr & 0x0000ffff); - __le32 data = cpu_to_le32(val & 0x0000ffff); + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; + __le16 data = cpu_to_le16(val); + int ret; + + ret = usb_write(intf, value, &data, 2); - return usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_WRITE); + return RTW_STATUS_CODE(ret); } -static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +int rtw_write32(struct adapter *adapter, u32 addr, u32 val) { - u16 wvalue = (u16)(addr & 0x0000ffff); + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; __le32 data = cpu_to_le32(val); + int ret; - return usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_WRITE); + ret = usb_write(intf, value, &data, 4); + + return RTW_STATUS_CODE(ret); } -static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) +int rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *data) { - u16 wvalue = (u16)(addr & 0x0000ffff); - u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0}; + struct io_priv *io_priv = &adapter->iopriv; + struct intf_hdl *intf = &io_priv->intf; + u16 value = addr & 0xffff; + int ret; if (length > VENDOR_CMD_MAX_DATA_LEN) - return -EINVAL; + return _FAIL; - memcpy(buf, pdata, length); + ret = usb_write(intf, value, data, length); - return usbctrl_vendorreq(pintfhdl, wvalue, buf, (length & 0xffff), REALTEK_USB_VENQT_WRITE); + return RTW_STATUS_CODE(ret); } static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf) @@ -415,10 +435,6 @@ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) break; case -EPROTO: case -EOVERFLOW: - { - struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); - haldata->srestpriv.wifi_error_status = USB_READ_PORT_FAIL; - } precvbuf->reuse = true; rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); break; @@ -431,11 +447,10 @@ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) } } -static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +u32 rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *rmem) { struct urb *purb = NULL; struct recv_buf *precvbuf = (struct recv_buf *)rmem; - struct adapter *adapter = pintfhdl->padapter; struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); struct recv_priv *precvpriv = &adapter->recvpriv; struct usb_device *pusbd = pdvobj->pusbdev; @@ -458,7 +473,7 @@ static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) precvbuf->reuse = true; } - rtl8188eu_init_recvbuf(adapter, precvbuf); + rtl8188eu_init_recvbuf(precvbuf); /* re-assign for linux based on skb */ if (!precvbuf->reuse || !precvbuf->pskb) { @@ -533,30 +548,3 @@ void rtl8188eu_xmit_tasklet(unsigned long priv) break; } } - -void rtl8188eu_set_intf_ops(struct _io_ops *pops) -{ - - memset((u8 *)pops, 0, sizeof(struct _io_ops)); - pops->_read8 = &usb_read8; - pops->_read16 = &usb_read16; - pops->_read32 = &usb_read32; - pops->_read_mem = &usb_read_mem; - pops->_read_port = &usb_read_port; - pops->_write8 = &usb_write8; - pops->_write16 = &usb_write16; - pops->_write32 = &usb_write32; - pops->_writeN = &usb_writeN; - pops->_write_mem = &usb_write_mem; - pops->_write_port = &usb_write_port; - pops->_read_port_cancel = &usb_read_port_cancel; - pops->_write_port_cancel = &usb_write_port_cancel; - -} - -void rtl8188eu_set_hw_type(struct adapter *adapt) -{ - adapt->chip_type = RTL8188E; - adapt->HardwareType = HARDWARE_TYPE_RTL8188EU; - DBG_88E("CHIP TYPE: RTL8188E\n"); -} |