#include "../../wusbcore/wusbhc.h"
#include "whcd.h"
struct whc_dbg {
struct dentry *di_f;
struct dentry *asl_f;
struct dentry *pzl_f;
};
static void qset_print(struct seq_file *s, struct whc_qset *qset)
{
static const char *qh_type[] = {
"ctrl", "isoc", "bulk", "intr", "rsvd", "rsvd", "rsvd", "lpintr", };
struct whc_std *std;
struct urb *urb = NULL;
int i;
seq_printf(s, "qset %08x", (u32)qset->qset_dma);
if (&qset->list_node == qset->whc->async_list.prev) {
seq_printf(s, " (dummy)\n");
} else {
seq_printf(s, " ep%d%s-%s maxpkt: %d\n",
qset->qh.info1 & 0x0f,
(qset->qh.info1 >> 4) & 0x1 ? "in" : "out",
qh_type[(qset->qh.info1 >> 5) & 0x7],
(qset->qh.info1 >> 16) & 0xffff);
}
seq_printf(s, " -> %08x\n", (u32)qset->qh.link);
seq_printf(s, " info: %08x %08x %08x\n",
qset->qh.info1, qset->qh.info2, qset->qh.info3);
seq_printf(s, " sts: %04x errs: %d curwin: %08x\n",
qset->qh.status, qset->qh.err_count, qset->qh.cur_window);
seq_printf(s, " TD: sts: %08x opts: %08x\n",
qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
seq_printf(s, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
i == qset->td_start ? 'S' : ' ',
i == qset->td_end ? 'E' : ' ',
i, qset->qtd[i].status, qset->qtd[i].options,
(u32)qset->qtd[i].page_list_ptr);
}
seq_printf(s, " ntds: %d\n", qset->ntds);
list_for_each_entry(std, &qset->stds, list_node) {
if (urb != std->urb) {
urb = std->urb;
seq_printf(s, " urb %p transferred: %d bytes\n", urb,
urb->actual_length);
}
if (std->qtd)
seq_printf(s, " sTD[%td]: %zu bytes @ %08x\n",
std->qtd - &qset->qtd[0],
std->len, std->num_pointers ?
(u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
else
seq_printf(s, " sTD[-]: %zd bytes @ %08x\n",
std->len, std->num_pointers ?
(u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
}
}
static int di_print(struct seq_file *s, void *p)
{
struct whc *whc = s->private;
int d;
for (d = 0; d < whc->n_devices; d++) {
struct di_buf_entry *di = &whc->di_buf[d];
seq_printf(s, "DI[%d]\n", d);
seq_printf(s, " availability: %*pb\n",
UWB_NUM_MAS, (unsigned long *)di->availability_info);
seq_printf(s, " %c%c key idx: %d dev addr: %d\n",
(di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
(di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
(di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
(di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
}
return 0;
}
static int asl_print(struct seq_file *s, void *p)
{
struct whc *whc = s->private;
struct whc_qset *qset;
list_for_each_entry(qset, &whc->async_list, list_node) {
qset_print(s, qset);
}
return 0;
}
static int pzl_print(struct seq_file *s, void *p)
{
struct whc *whc = s->private;
struct whc_qset *qset;
int period;
for (period = 0; period < 5; period++) {
seq_printf(s, "Period %d\n", period);
list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
qset_print(s, qset);
}
}
return 0;
}
static int di_open(struct inode *inode, struct file *file)
{
return single_open(file, di_print, inode->i_private);
}
static int asl_open(struct inode *inode, struct file *file)
{
return single_open(file, asl_print, inode->i_private);
}
static int pzl_open(struct inode *inode, struct file *file)
{
return single_open(file, pzl_print, inode->i_private);
}
static const struct file_operations di_fops = {
.open = di_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
static const struct file_operations asl_fops = {
.open = asl_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
static const struct file_operations pzl_fops = {
.open = pzl_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
void whc_dbg_init(struct whc *whc)
{
if (whc->wusbhc.pal.debugfs_dir == NULL)
return;
whc->dbg = kzalloc(sizeof(struct whc_dbg), GFP_KERNEL);
if (whc->dbg == NULL)
return;
whc->dbg->di_f = debugfs_create_file("di", 0444,
whc->wusbhc.pal.debugfs_dir, whc,
&di_fops);
whc->dbg->asl_f = debugfs_create_file("asl", 0444,
whc->wusbhc.pal.debugfs_dir, whc,
&asl_fops);
whc->dbg->pzl_f = debugfs_create_file("pzl", 0444,
whc->wusbhc.pal.debugfs_dir, whc,
&pzl_fops);
}
void whc_dbg_clean_up(struct whc *whc)
{
if (whc->dbg) {
debugfs_remove(whc->dbg->pzl_f);
debugfs_remove(whc->dbg->asl_f);
debugfs_remove(whc->dbg->di_f);
kfree(whc->dbg);
}
}
afd90bb16fa668e22 /drivers/usb/host/ohci-ppc-of.c
parent | 49def1853334396f948dcb4cedb9347abb318df5 (diff) |
USB: serial: qcserial: add Dell DW5570 QDL
The Dell DW5570 is a re-branded Sierra Wireless MC8805 which will by
default boot with vid 0x413c and pid 0x81a3. When triggered QDL download
mode, the device switches to pid 0x81a6 and provides the standard TTY
used for firmware upgrade.
Cc: <stable@vger.kernel.org>
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Signed-off-by: Johan Hovold <johan@kernel.org>