mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-23 01:40:30 +00:00
staging: gdm7240: a TTY rewrite according to the latest TTY APIs
Fixed mis-use of mutex for gdm_table. gdm_table is refered to only inside tty_install and port destrcut, and usb callbacks use internal reference which was saved during urb submission Signed-off-by: Won Kang <wonkang@gctsemi.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7ee4c1b949
commit
bf0373f1c6
@ -25,7 +25,6 @@
|
||||
#include <linux/usb/cdc.h>
|
||||
|
||||
#include "gdm_mux.h"
|
||||
#include "gdm_tty.h"
|
||||
|
||||
struct workqueue_struct *mux_rx_wq;
|
||||
|
||||
@ -196,7 +195,7 @@ static int up_to_host(struct mux_rx *r)
|
||||
ret = r->callback(mux_header->data,
|
||||
payload_size,
|
||||
index,
|
||||
mux_dev->minor[index],
|
||||
mux_dev->tty_dev,
|
||||
RECV_PACKET_PROCESS_CONTINUE
|
||||
);
|
||||
if (ret == TO_HOST_BUFFER_REQUEST_FAIL) {
|
||||
@ -209,7 +208,7 @@ static int up_to_host(struct mux_rx *r)
|
||||
ret = r->callback(NULL,
|
||||
0,
|
||||
index,
|
||||
mux_dev->minor[index],
|
||||
mux_dev->tty_dev,
|
||||
RECV_PACKET_PROCESS_COMPLETE
|
||||
);
|
||||
break;
|
||||
@ -283,7 +282,7 @@ static void gdm_mux_rcv_complete(struct urb *urb)
|
||||
}
|
||||
|
||||
static int gdm_mux_recv(void *priv_dev,
|
||||
int (*cb)(void *data, int len, int tty_index, int minor, int complete)
|
||||
int (*cb)(void *data, int len, int tty_index, struct tty_dev *tty_dev, int complete)
|
||||
)
|
||||
{
|
||||
struct mux_dev *mux_dev = priv_dev;
|
||||
@ -562,7 +561,7 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < TTY_MAX_COUNT; i++)
|
||||
mux_dev->minor[i] = tty_dev->minor[i];
|
||||
mux_dev->tty_dev = tty_dev;
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <linux/usb.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "gdm_tty.h"
|
||||
|
||||
#define PM_NORMAL 0
|
||||
#define PM_SUSPEND 1
|
||||
|
||||
@ -57,7 +59,10 @@ struct mux_rx {
|
||||
void *mux_dev;
|
||||
u32 offset;
|
||||
u32 len;
|
||||
int (*callback)(void *data, int len, int tty_index, int minor,
|
||||
int (*callback)(void *data,
|
||||
int len,
|
||||
int tty_index,
|
||||
struct tty_dev *tty_dev,
|
||||
int complete);
|
||||
};
|
||||
|
||||
@ -78,10 +83,13 @@ struct mux_dev {
|
||||
struct delayed_work work_rx;
|
||||
struct usb_interface *intf;
|
||||
int usb_state;
|
||||
int (*rx_cb)(void *data, int len, int tty_index, int minor,
|
||||
int (*rx_cb)(void *data,
|
||||
int len,
|
||||
int tty_index,
|
||||
struct tty_dev *tty_dev,
|
||||
int complete);
|
||||
spinlock_t write_lock;
|
||||
u8 minor[2];
|
||||
struct tty_dev *tty_dev;
|
||||
};
|
||||
|
||||
#endif /* _GDM_MUX_H_ */
|
||||
|
@ -89,19 +89,22 @@ static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||
|
||||
mutex_lock(&gdm_table_lock);
|
||||
gdm = gdm_table[i][j];
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
if (gdm == NULL)
|
||||
if (gdm == NULL) {
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
tty_port_get(&gdm->port);
|
||||
|
||||
ret = tty_standard_install(driver, tty);
|
||||
if (ret) {
|
||||
tty_port_put(&gdm->port);
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tty->driver_data = gdm;
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -130,14 +133,13 @@ static void gdm_tty_close(struct tty_struct *tty, struct file *filp)
|
||||
tty_port_close(&gdm->port, tty, filp);
|
||||
}
|
||||
|
||||
static int gdm_tty_recv_complete(void *data, int len, int index, int minor, int complete)
|
||||
static int gdm_tty_recv_complete(void *data,
|
||||
int len,
|
||||
int index,
|
||||
struct tty_dev *tty_dev,
|
||||
int complete)
|
||||
{
|
||||
struct gdm *gdm;
|
||||
|
||||
mutex_lock(&gdm_table_lock);
|
||||
gdm = gdm_table[index][minor];
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
|
||||
struct gdm *gdm = tty_dev->gdm[index];
|
||||
if (!GDM_TTY_READY(gdm)) {
|
||||
if (complete == RECV_PACKET_PROCESS_COMPLETE)
|
||||
gdm_tty_recv(gdm, gdm_tty_recv_complete);
|
||||
@ -223,31 +225,29 @@ int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&gdm_table_lock);
|
||||
|
||||
for (j = 0; j < GDM_TTY_MINOR; j++) {
|
||||
if (!gdm_table[i][j])
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == GDM_TTY_MINOR) {
|
||||
tty_dev->minor[i] = GDM_TTY_MINOR;
|
||||
kfree(gdm);
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gdm_table[i][j] = gdm;
|
||||
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
|
||||
tty_dev->minor[i] = j;
|
||||
|
||||
tty_dev->gdm[i] = gdm;
|
||||
tty_port_init(&gdm->port);
|
||||
|
||||
gdm->port.ops = &gdm_port_ops;
|
||||
gdm->index = i;
|
||||
gdm->minor = j;
|
||||
gdm->tty_dev = tty_dev;
|
||||
|
||||
tty_port_register_device(&gdm->port, gdm_driver[i], j, device);
|
||||
tty_port_register_device(&gdm->port, gdm_driver[i], gdm->minor, device);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_ISSUE_NUM; i++)
|
||||
@ -261,31 +261,24 @@ void unregister_lte_tty_device(struct tty_dev *tty_dev)
|
||||
struct gdm *gdm;
|
||||
struct tty_struct *tty;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < TTY_MAX_COUNT; i++) {
|
||||
|
||||
j = tty_dev->minor[i];
|
||||
|
||||
if (j >= GDM_TTY_MINOR)
|
||||
gdm = tty_dev->gdm[i];
|
||||
if (!gdm)
|
||||
continue;
|
||||
|
||||
mutex_lock(&gdm_table_lock);
|
||||
gdm = gdm_table[i][j];
|
||||
gdm_table[gdm->index][gdm->minor] = NULL;
|
||||
mutex_unlock(&gdm_table_lock);
|
||||
|
||||
if (!gdm)
|
||||
continue;
|
||||
|
||||
tty = tty_port_tty_get(&gdm->port);
|
||||
if (tty) {
|
||||
tty_vhangup(tty);
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
|
||||
tty_unregister_device(gdm_driver[i], j);
|
||||
tty_unregister_device(gdm_driver[i], gdm->minor);
|
||||
tty_port_put(&gdm->port);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,17 +33,6 @@ enum RECV_PACKET_PROCESS {
|
||||
RECV_PACKET_PROCESS_CONTINUE = 1,
|
||||
};
|
||||
|
||||
struct tty_dev {
|
||||
void *priv_dev;
|
||||
int (*send_func)(void *priv_dev, void *data, int len, int tty_index,
|
||||
void (*cb)(void *cb_data), void *cb_data);
|
||||
int (*recv_func)(void *priv_dev, int (*cb)(void *data, int len,
|
||||
int tty_index, int minor, int complete));
|
||||
int (*send_control)(void *priv_dev, int request, int value, void *data,
|
||||
int len);
|
||||
u8 minor[2];
|
||||
};
|
||||
|
||||
struct gdm {
|
||||
struct tty_dev *tty_dev;
|
||||
struct tty_port port;
|
||||
@ -51,6 +40,28 @@ struct gdm {
|
||||
unsigned int minor;
|
||||
};
|
||||
|
||||
struct tty_dev {
|
||||
void *priv_dev;
|
||||
int (*send_func)(void *priv_dev,
|
||||
void *data,
|
||||
int len,
|
||||
int tty_index,
|
||||
void (*cb)(void *cb_data),
|
||||
void *cb_data);
|
||||
int (*recv_func)(void *priv_dev,
|
||||
int (*cb)(void *data,
|
||||
int len,
|
||||
int tty_index,
|
||||
struct tty_dev *tty_dev,
|
||||
int complete));
|
||||
int (*send_control)(void *priv_dev,
|
||||
int request,
|
||||
int value,
|
||||
void *data,
|
||||
int len);
|
||||
struct gdm *gdm[2];
|
||||
};
|
||||
|
||||
int register_lte_tty_driver(void);
|
||||
void unregister_lte_tty_driver(void);
|
||||
int register_lte_tty_device(struct tty_dev *tty_dev, struct device *dev);
|
||||
|
Loading…
Reference in New Issue
Block a user