Commit 4de7c278 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.6
parents 9b1c0e63 8cdcd722
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/parser.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
static struct super_operations usbfs_ops; static struct super_operations usbfs_ops;
...@@ -62,76 +63,87 @@ static umode_t devmode = S_IWUSR | S_IRUGO; ...@@ -62,76 +63,87 @@ static umode_t devmode = S_IWUSR | S_IRUGO;
static umode_t busmode = S_IXUGO | S_IRUGO; static umode_t busmode = S_IXUGO | S_IRUGO;
static umode_t listmode = S_IRUGO; static umode_t listmode = S_IRUGO;
enum {
Opt_devuid, Opt_devgid, Opt_devmode,
Opt_busuid, Opt_busgid, Opt_busmode,
Opt_listuid, Opt_listgid, Opt_listmode,
Opt_err,
};
static match_table_t tokens = {
{Opt_devuid, "devuid=%u"},
{Opt_devgid, "devgid=%u"},
{Opt_devmode, "devmode=%o"},
{Opt_busuid, "busuid=%u"},
{Opt_busgid, "busgid=%u"},
{Opt_busmode, "busmode=%o"},
{Opt_listuid, "listuid=%u"},
{Opt_listgid, "listgid=%u"},
{Opt_listmode, "listmode=%o"},
{Opt_err, NULL}
};
static int parse_options(struct super_block *s, char *data) static int parse_options(struct super_block *s, char *data)
{ {
char *curopt = NULL, *value; char *p;
int option;
while ((curopt = strsep(&data, ",")) != NULL) { while ((p = strsep(&data, ",")) != NULL) {
if (!*curopt) substring_t args[MAX_OPT_ARGS];
int token;
if (!*p)
continue; continue;
if ((value = strchr(curopt, '=')) != NULL)
*value++ = 0; token = match_token(p, tokens, args);
if (!strcmp(curopt, "devuid")) { switch (token) {
if (!value || !value[0]) case Opt_devuid:
return -EINVAL; if (match_int(&args[0], &option))
devuid = simple_strtoul(value, &value, 0);
if (*value)
return -EINVAL;
}
if (!strcmp(curopt, "devgid")) {
if (!value || !value[0])
return -EINVAL;
devgid = simple_strtoul(value, &value, 0);
if (*value)
return -EINVAL;
}
if (!strcmp(curopt, "devmode")) {
if (!value || !value[0])
return -EINVAL;
devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
if (*value)
return -EINVAL;
}
if (!strcmp(curopt, "busuid")) {
if (!value || !value[0])
return -EINVAL;
busuid = simple_strtoul(value, &value, 0);
if (*value)
return -EINVAL;
}
if (!strcmp(curopt, "busgid")) {
if (!value || !value[0])
return -EINVAL; return -EINVAL;
busgid = simple_strtoul(value, &value, 0); devuid = option;
if (*value) break;
case Opt_devgid:
if (match_int(&args[0], &option))
return -EINVAL; return -EINVAL;
} devgid = option;
if (!strcmp(curopt, "busmode")) { break;
if (!value || !value[0]) case Opt_devmode:
if (match_octal(&args[0], &option))
return -EINVAL; return -EINVAL;
busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO; devmode = option & S_IRWXUGO;
if (*value) break;
case Opt_busuid:
if (match_int(&args[0], &option))
return -EINVAL; return -EINVAL;
} busuid = option;
if (!strcmp(curopt, "listuid")) { break;
if (!value || !value[0]) case Opt_busgid:
if (match_int(&args[0], &option))
return -EINVAL; return -EINVAL;
listuid = simple_strtoul(value, &value, 0); busgid = option;
if (*value) break;
case Opt_busmode:
if (match_octal(&args[0], &option))
return -EINVAL; return -EINVAL;
} busmode = option & S_IRWXUGO;
if (!strcmp(curopt, "listgid")) { break;
if (!value || !value[0]) case Opt_listuid:
if (match_int(&args[0], &option))
return -EINVAL; return -EINVAL;
listgid = simple_strtoul(value, &value, 0); listuid = option;
if (*value) break;
case Opt_listgid:
if (match_int(&args[0], &option))
return -EINVAL; return -EINVAL;
} listgid = option;
if (!strcmp(curopt, "listmode")) { break;
if (!value || !value[0]) case Opt_listmode:
if (match_octal(&args[0], &option))
return -EINVAL; return -EINVAL;
listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO; listmode = option & S_IRWXUGO;
if (*value) break;
default:
err("usbfs: unrecognised mount option \"%s\" "
"or missing value\n", p);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -139,9 +151,6 @@ static int parse_options(struct super_block *s, char *data) ...@@ -139,9 +151,6 @@ static int parse_options(struct super_block *s, char *data)
return 0; return 0;
} }
/* --------------------------------------------------------------------- */
static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev) static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev)
{ {
struct inode *inode = new_inode(sb); struct inode *inode = new_inode(sb);
......
...@@ -99,82 +99,6 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) ...@@ -99,82 +99,6 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space)
return out - buf; return out - buf;
} }
static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
{
char *out = buf;
/* Try to make sure there's enough memory */
if (len < 80)
return 0;
out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s\n",
port,
status,
(status & USBPORTSC_SUSP) ? "PortSuspend " : "",
(status & USBPORTSC_PR) ? "PortReset " : "",
(status & USBPORTSC_LSDA) ? "LowSpeed " : "",
(status & USBPORTSC_RD) ? "ResumeDetect " : "",
(status & USBPORTSC_PEC) ? "EnableChange " : "",
(status & USBPORTSC_PE) ? "PortEnabled " : "",
(status & USBPORTSC_CSC) ? "ConnectChange " : "",
(status & USBPORTSC_CCS) ? "PortConnected " : "");
return out - buf;
}
static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
{
char *out = buf;
unsigned int io_addr = uhci->io_addr;
unsigned short usbcmd, usbstat, usbint, usbfrnum;
unsigned int flbaseadd;
unsigned char sof;
unsigned short portsc1, portsc2;
/* Try to make sure there's enough memory */
if (len < 80 * 6)
return 0;
usbcmd = inw(io_addr + 0);
usbstat = inw(io_addr + 2);
usbint = inw(io_addr + 4);
usbfrnum = inw(io_addr + 6);
flbaseadd = inl(io_addr + 8);
sof = inb(io_addr + 12);
portsc1 = inw(io_addr + 16);
portsc2 = inw(io_addr + 18);
out += sprintf(out, " usbcmd = %04x %s%s%s%s%s%s%s%s\n",
usbcmd,
(usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
(usbcmd & USBCMD_CF) ? "CF " : "",
(usbcmd & USBCMD_SWDBG) ? "SWDBG " : "",
(usbcmd & USBCMD_FGR) ? "FGR " : "",
(usbcmd & USBCMD_EGSM) ? "EGSM " : "",
(usbcmd & USBCMD_GRESET) ? "GRESET " : "",
(usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
(usbcmd & USBCMD_RS) ? "RS " : "");
out += sprintf(out, " usbstat = %04x %s%s%s%s%s%s\n",
usbstat,
(usbstat & USBSTS_HCH) ? "HCHalted " : "",
(usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
(usbstat & USBSTS_HSE) ? "HostSystemError " : "",
(usbstat & USBSTS_RD) ? "ResumeDetect " : "",
(usbstat & USBSTS_ERROR) ? "USBError " : "",
(usbstat & USBSTS_USBINT) ? "USBINT " : "");
out += sprintf(out, " usbint = %04x\n", usbint);
out += sprintf(out, " usbfrnum = (%d)%03x\n", (usbfrnum >> 10) & 1,
0xfff & (4*(unsigned int)usbfrnum));
out += sprintf(out, " flbaseadd = %08x\n", flbaseadd);
out += sprintf(out, " sof = %02x\n", sof);
out += uhci_show_sc(1, portsc1, out, len - (out - buf));
out += uhci_show_sc(2, portsc2, out, len - (out - buf));
return out - buf;
}
static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
{ {
char *out = buf; char *out = buf;
...@@ -274,6 +198,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) ...@@ -274,6 +198,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
return out - buf; return out - buf;
} }
#define show_frame_num() \
if (!shown) { \
shown = 1; \
out += sprintf(out, "- Frame %d\n", i); \
}
#ifdef CONFIG_PROC_FS
static const char *qh_names[] = { static const char *qh_names[] = {
"skel_int128_qh", "skel_int64_qh", "skel_int128_qh", "skel_int64_qh",
"skel_int32_qh", "skel_int16_qh", "skel_int32_qh", "skel_int16_qh",
...@@ -283,18 +214,88 @@ static const char *qh_names[] = { ...@@ -283,18 +214,88 @@ static const char *qh_names[] = {
"skel_bulk_qh", "skel_term_qh" "skel_bulk_qh", "skel_term_qh"
}; };
#define show_frame_num() \
if (!shown) { \
shown = 1; \
out += sprintf(out, "- Frame %d\n", i); \
}
#define show_qh_name() \ #define show_qh_name() \
if (!shown) { \ if (!shown) { \
shown = 1; \ shown = 1; \
out += sprintf(out, "- %s\n", qh_names[i]); \ out += sprintf(out, "- %s\n", qh_names[i]); \
} }
static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
{
char *out = buf;
/* Try to make sure there's enough memory */
if (len < 80)
return 0;
out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s\n",
port,
status,
(status & USBPORTSC_SUSP) ? "PortSuspend " : "",
(status & USBPORTSC_PR) ? "PortReset " : "",
(status & USBPORTSC_LSDA) ? "LowSpeed " : "",
(status & USBPORTSC_RD) ? "ResumeDetect " : "",
(status & USBPORTSC_PEC) ? "EnableChange " : "",
(status & USBPORTSC_PE) ? "PortEnabled " : "",
(status & USBPORTSC_CSC) ? "ConnectChange " : "",
(status & USBPORTSC_CCS) ? "PortConnected " : "");
return out - buf;
}
static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
{
char *out = buf;
unsigned int io_addr = uhci->io_addr;
unsigned short usbcmd, usbstat, usbint, usbfrnum;
unsigned int flbaseadd;
unsigned char sof;
unsigned short portsc1, portsc2;
/* Try to make sure there's enough memory */
if (len < 80 * 6)
return 0;
usbcmd = inw(io_addr + 0);
usbstat = inw(io_addr + 2);
usbint = inw(io_addr + 4);
usbfrnum = inw(io_addr + 6);
flbaseadd = inl(io_addr + 8);
sof = inb(io_addr + 12);
portsc1 = inw(io_addr + 16);
portsc2 = inw(io_addr + 18);
out += sprintf(out, " usbcmd = %04x %s%s%s%s%s%s%s%s\n",
usbcmd,
(usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
(usbcmd & USBCMD_CF) ? "CF " : "",
(usbcmd & USBCMD_SWDBG) ? "SWDBG " : "",
(usbcmd & USBCMD_FGR) ? "FGR " : "",
(usbcmd & USBCMD_EGSM) ? "EGSM " : "",
(usbcmd & USBCMD_GRESET) ? "GRESET " : "",
(usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
(usbcmd & USBCMD_RS) ? "RS " : "");
out += sprintf(out, " usbstat = %04x %s%s%s%s%s%s\n",
usbstat,
(usbstat & USBSTS_HCH) ? "HCHalted " : "",
(usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
(usbstat & USBSTS_HSE) ? "HostSystemError " : "",
(usbstat & USBSTS_RD) ? "ResumeDetect " : "",
(usbstat & USBSTS_ERROR) ? "USBError " : "",
(usbstat & USBSTS_USBINT) ? "USBINT " : "");
out += sprintf(out, " usbint = %04x\n", usbint);
out += sprintf(out, " usbfrnum = (%d)%03x\n", (usbfrnum >> 10) & 1,
0xfff & (4*(unsigned int)usbfrnum));
out += sprintf(out, " flbaseadd = %08x\n", flbaseadd);
out += sprintf(out, " sof = %02x\n", sof);
out += uhci_show_sc(1, portsc1, out, len - (out - buf));
out += uhci_show_sc(2, portsc2, out, len - (out - buf));
return out - buf;
}
static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *buf, int len) static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *buf, int len)
{ {
struct list_head *tmp; struct list_head *tmp;
...@@ -512,7 +513,6 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) ...@@ -512,7 +513,6 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
return out - buf; return out - buf;
} }
#ifdef CONFIG_PROC_FS
#define MAX_OUTPUT (64 * 1024) #define MAX_OUTPUT (64 * 1024)
static struct proc_dir_entry *uhci_proc_root = NULL; static struct proc_dir_entry *uhci_proc_root = NULL;
......
...@@ -2185,8 +2185,8 @@ static int uhci_reset(struct usb_hcd *hcd) ...@@ -2185,8 +2185,8 @@ static int uhci_reset(struct usb_hcd *hcd)
/* Maybe kick BIOS off this hardware. Then reset, so we won't get /* Maybe kick BIOS off this hardware. Then reset, so we won't get
* interrupts from any previous setup. * interrupts from any previous setup.
*/ */
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
reset_hc(uhci); reset_hc(uhci);
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
return 0; return 0;
} }
......
...@@ -186,8 +186,5 @@ config USB_XPAD ...@@ -186,8 +186,5 @@ config USB_XPAD
For information about how to connect the X-Box pad to USB, see For information about how to connect the X-Box pad to USB, see
Documentation/input/xpad.txt. Documentation/input/xpad.txt.
This driver is also available as a module ( = code which can be To compile this driver as a module, choose M here: the
inserted in and removed from the running kernel whenever you want). module will be called xpad.
The module will be called xpad. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
...@@ -591,14 +591,14 @@ brlvger_write(struct file *file, const char __user *buffer, ...@@ -591,14 +591,14 @@ brlvger_write(struct file *file, const char __user *buffer,
int firstpart = 6 - off; int firstpart = 6 - off;
#ifdef WRITE_DEBUG #ifdef WRITE_DEBUG
dbg3("off: %d, rs: %d, count: %d, firstpart: %d", dbg3("off: %lld, rs: %d, count: %d, firstpart: %d",
off, rs, count, firstpart); off, rs, count, firstpart);
#endif #endif
firstpart = (firstpart < count) ? firstpart : count; firstpart = (firstpart < count) ? firstpart : count;
#ifdef WRITE_DEBUG #ifdef WRITE_DEBUG
dbg3("off: %d", off); dbg3("off: %lld", off);
dbg3("firstpart: %d", firstpart); dbg3("firstpart: %d", firstpart);
#endif #endif
...@@ -618,7 +618,7 @@ brlvger_write(struct file *file, const char __user *buffer, ...@@ -618,7 +618,7 @@ brlvger_write(struct file *file, const char __user *buffer,
off +=2; off +=2;
#ifdef WRITE_DEBUG #ifdef WRITE_DEBUG
dbg3("off: %d, rs: %d, count: %d, firstpart: %d, " dbg3("off: %lld, rs: %d, count: %d, firstpart: %d, "
"written: %d", off, rs, count, firstpart, written); "written: %d", off, rs, count, firstpart, written);
#endif #endif
} }
......
...@@ -189,8 +189,7 @@ struct udsl_vcc_data { ...@@ -189,8 +189,7 @@ struct udsl_vcc_data {
struct atm_vcc *vcc; struct atm_vcc *vcc;
/* raw cell reassembly */ /* raw cell reassembly */
struct sk_buff *skb; struct sk_buff *sarb;
unsigned int max_pdu;
}; };
/* send */ /* send */
...@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch ...@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
{ {
struct udsl_vcc_data *cached_vcc = NULL; struct udsl_vcc_data *cached_vcc = NULL;
struct atm_vcc *vcc; struct atm_vcc *vcc;
struct sk_buff *skb; struct sk_buff *sarb;
struct udsl_vcc_data *vcc_data; struct udsl_vcc_data *vcc_data;
int cached_vci = 0; int cached_vci = 0;
unsigned int i; unsigned int i;
unsigned int length;
unsigned int pdu_length;
int pti; int pti;
int vci; int vci;
short cached_vpi = 0; short cached_vpi = 0;
...@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch ...@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
} }
vcc = vcc_data->vcc; vcc = vcc_data->vcc;
sarb = vcc_data->sarb;
if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) { if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc); dbg ("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
if (pti)
atomic_inc (&vcc->stats->rx_err);
continue;
}
skb = vcc_data->skb;
if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
/* discard cells already received */ /* discard cells already received */
skb_trim (skb, 0); skb_trim (sarb, 0);
DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
} }
memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); memcpy (sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
__skb_put (skb, ATM_CELL_PAYLOAD); __skb_put (sarb, ATM_CELL_PAYLOAD);
if (pti) { if (pti) {
struct sk_buff *skb;
unsigned int length;
unsigned int pdu_length;
length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5]; length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
/* guard against overflow */ /* guard against overflow */
if (length > ATM_MAX_AAL5_PDU) { if (length > ATM_MAX_AAL5_PDU) {
dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc); dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD; pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
if (skb->len < pdu_length) { if (sarb->len < pdu_length) {
dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc); dbg ("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) { if (crc32_be (~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc); dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
if (!atm_charge (vcc, skb->truesize)) { vdbg ("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
goto drop_no_stats; /* atm_charge increments rx_drop */
}
/* now that we are sure to send the skb, it is ok to change skb->data */ if (!(skb = dev_alloc_skb (length))) {
if (skb->len > pdu_length) dbg ("udsl_extract_cells: no memory for skb (length: %u)!", length);
skb_pull (skb, skb->len - pdu_length); /* discard initial junk */ atomic_inc (&vcc->stats->rx_drop);
goto out;
}
skb_trim (skb, length); /* drop zero padding and trailer */ vdbg ("udsl_extract_cells: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", skb, skb->truesize);
atomic_inc (&vcc->stats->rx); if (!atm_charge (vcc, skb->truesize)) {
dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)!", skb->truesize);
dev_kfree_skb (skb);
goto out; /* atm_charge increments rx_drop */
}
PACKETDEBUG (skb->data, skb->len); memcpy (skb->data, sarb->tail - pdu_length, length);
__skb_put (skb, length);
vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize); vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
vcc->push (vcc, skb); PACKETDEBUG (skb->data, skb->len);
vcc_data->skb = NULL;
continue; vcc->push (vcc, skb);
drop: atomic_inc (&vcc->stats->rx);
atomic_inc (&vcc->stats->rx_err); out:
drop_no_stats: skb_trim (sarb, 0);
skb_trim (skb, 0);
} }
} }
} }
...@@ -871,6 +867,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -871,6 +867,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{ {
struct udsl_instance_data *instance = vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *new; struct udsl_vcc_data *new;
unsigned int max_pdu;
dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci); dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
...@@ -883,8 +880,10 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -883,8 +880,10 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL; return -EINVAL;
/* only support AAL5 */ /* only support AAL5 */
if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
return -EINVAL; return -EINVAL;
}
if (!instance->firmware_loaded) { if (!instance->firmware_loaded) {
dbg ("udsl_atm_open: firmware not loaded!"); dbg ("udsl_atm_open: firmware not loaded!");
...@@ -894,11 +893,13 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -894,11 +893,13 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
down (&instance->serialize); /* vs self, udsl_atm_close */ down (&instance->serialize); /* vs self, udsl_atm_close */
if (udsl_find_vcc (instance, vpi, vci)) { if (udsl_find_vcc (instance, vpi, vci)) {
dbg ("udsl_atm_open: %hd/%d already in use!", vpi, vci);
up (&instance->serialize); up (&instance->serialize);
return -EADDRINUSE; return -EADDRINUSE;
} }
if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) { if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
dbg ("udsl_atm_open: no memory for vcc_data!");
up (&instance->serialize); up (&instance->serialize);
return -ENOMEM; return -ENOMEM;
} }
...@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
new->vcc = vcc; new->vcc = vcc;
new->vpi = vpi; new->vpi = vpi;
new->vci = vci; new->vci = vci;
new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
/* udsl_extract_cells requires at least one cell */
max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
if (!(new->sarb = alloc_skb (max_pdu, GFP_KERNEL))) {
dbg ("udsl_atm_open: no memory for SAR buffer!");
kfree (new);
up (&instance->serialize);
return -ENOMEM;
}
vcc->dev_data = new; vcc->dev_data = new;
vcc->vpi = vpi; vcc->vpi = vpi;
...@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
tasklet_schedule (&instance->receive_tasklet); tasklet_schedule (&instance->receive_tasklet);
dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu); dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);
return 0; return 0;
} }
...@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_vcc *vcc) ...@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_vcc *vcc)
list_del (&vcc_data->list); list_del (&vcc_data->list);
tasklet_enable (&instance->receive_tasklet); tasklet_enable (&instance->receive_tasklet);
if (vcc_data->skb) kfree_skb (vcc_data->sarb);
dev_kfree_skb (vcc_data->skb); vcc_data->sarb = NULL;
vcc_data->skb = NULL;
kfree (vcc_data); kfree (vcc_data);
vcc->dev_data = NULL; vcc->dev_data = NULL;
...@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_rcv_urbs; i++) for (i = 0; i < num_rcv_urbs; i++)
if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0) if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d!", i, result);
/* wait for completion handlers to finish */ /* wait for completion handlers to finish */
do { do {
...@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_snd_urbs; i++) for (i = 0; i < num_snd_urbs; i++)
if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0) if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d!", i, result);
/* wait for completion handlers to finish */ /* wait for completion handlers to finish */
do { do {
...@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static int __init udsl_usb_init (void) static int __init udsl_usb_init (void)
{ {
struct sk_buff *skb; /* dummy for sizeof */
dbg ("udsl_usb_init: driver version " DRIVER_VERSION); dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
if (sizeof (struct udsl_control) > sizeof (skb->cb)) { if (sizeof (struct udsl_control) > sizeof (((struct sk_buff *)0)->cb)) {
printk (KERN_ERR __FILE__ ": unusable with this kernel!\n"); printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
return -EIO; return -EIO;
} }
......
...@@ -102,6 +102,7 @@ struct freecom_status { ...@@ -102,6 +102,7 @@ struct freecom_status {
/* All packets (except for status) are 64 bytes long. */ /* All packets (except for status) are 64 bytes long. */
#define FCM_PACKET_LENGTH 64 #define FCM_PACKET_LENGTH 64
#define FCM_STATUS_PACKET_LENGTH 4
static int static int
freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
...@@ -216,7 +217,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -216,7 +217,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* There are times we can optimize out this status read, but it /* There are times we can optimize out this status read, but it
* doesn't hurt us to always do it now. */ * doesn't hurt us to always do it now. */
result = usb_stor_bulk_transfer_buf (us, ipipe, fst, result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial); FCM_STATUS_PACKET_LENGTH, &partial);
US_DEBUGP("foo Status result %d %u\n", result, partial); US_DEBUGP("foo Status result %d %u\n", result, partial);
if (result != USB_STOR_XFER_GOOD) if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
...@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get the data */ /* get the data */
result = usb_stor_bulk_transfer_buf (us, ipipe, fst, result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial); FCM_STATUS_PACKET_LENGTH, &partial);
US_DEBUGP("bar Status result %d %u\n", result, partial); US_DEBUGP("bar Status result %d %u\n", result, partial);
if (result > USB_STOR_XFER_SHORT) if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial)); US_DEBUG(pdump ((void *) fst, partial));
...@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
switch (us->srb->sc_data_direction) { switch (us->srb->sc_data_direction) {
case SCSI_DATA_READ: case SCSI_DATA_READ:
/* catch bogus "read 0 length" case */
if (!length)
break;
/* Make sure that the status indicates that the device /* Make sure that the status indicates that the device
* wants data as well. */ * wants data as well. */
if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
...@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break; break;
case SCSI_DATA_WRITE: case SCSI_DATA_WRITE:
/* catch bogus "write 0 length" case */
if (!length)
break;
/* Make sure the status indicates that the device wants to /* Make sure the status indicates that the device wants to
* send us data. */ * send us data. */
/* !!IMPLEMENT!! */ /* !!IMPLEMENT!! */
...@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break; break;
default: default:
/* should never hit here -- filtered in usb.c */
US_DEBUGP ("freecom unimplemented direction: %d\n", US_DEBUGP ("freecom unimplemented direction: %d\n",
us->srb->sc_data_direction); us->srb->sc_data_direction);
// Return fail, SCSI seems to handle this better. // Return fail, SCSI seems to handle this better.
......
...@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001, ...@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
"Dimage F300", "Dimage F300",
US_SC_SCSI, US_PR_BULK, NULL, 0 ), US_SC_SCSI, US_PR_BULK, NULL, 0 ),
/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001,
"Minolta",
"DIMAGE E223",
US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100,
"Hagiwara", "Hagiwara",
"FlashGate SmartMedia", "FlashGate SmartMedia",
...@@ -542,7 +548,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, ...@@ -542,7 +548,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
* - They don't like the INQUIRY command. So we must handle this command * - They don't like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves. * of the SCSI layer ourselves.
*/ */
UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x5009,
"Casio", "Casio",
"QV DigitalCamera", "QV DigitalCamera",
US_SC_8070, US_PR_CB, NULL, US_SC_8070, US_PR_CB, NULL,
......
...@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *dev, char *id, int index); ...@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *dev, char *id, int index);
#define dbg(format, arg...) do {} while (0) #define dbg(format, arg...) do {} while (0)
#endif #endif
#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg) #define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment