mlx4_en: Fix a kernel panic when waking tx queue
[safe/jmp/linux-2.6] / drivers / pcmcia / cistpl.c
index 1a513d9..4a110b7 100644 (file)
@@ -351,8 +351,11 @@ int verify_cis_cache(struct pcmcia_socket *s)
        char *buf;
 
        buf = kmalloc(256, GFP_KERNEL);
-       if (buf == NULL)
-               return -1;
+       if (buf == NULL) {
+               dev_printk(KERN_WARNING, &s->dev,
+                          "no memory for verifying CIS\n");
+               return -ENOMEM;
+       }
        list_for_each_entry(cis, &s->cis_cache, node) {
                int len = cis->len;
 
@@ -384,15 +387,19 @@ int verify_cis_cache(struct pcmcia_socket *s)
 int pcmcia_replace_cis(struct pcmcia_socket *s,
                       const u8 *data, const size_t len)
 {
-    if (len > CISTPL_MAX_CIS_SIZE)
-       return CS_BAD_SIZE;
-    kfree(s->fake_cis);
-    s->fake_cis = kmalloc(len, GFP_KERNEL);
-    if (s->fake_cis == NULL)
-       return CS_OUT_OF_RESOURCE;
-    s->fake_cis_len = len;
-    memcpy(s->fake_cis, data, len);
-    return 0;
+       if (len > CISTPL_MAX_CIS_SIZE) {
+               dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
+               return -EINVAL;
+       }
+       kfree(s->fake_cis);
+       s->fake_cis = kmalloc(len, GFP_KERNEL);
+       if (s->fake_cis == NULL) {
+               dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
+               return -ENOMEM;
+       }
+       s->fake_cis_len = len;
+       memcpy(s->fake_cis, data, len);
+       return 0;
 }
 EXPORT_SYMBOL(pcmcia_replace_cis);
 
@@ -419,9 +426,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *t
 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
 {
     if (!s)
-       return CS_BAD_HANDLE;
+       return -EINVAL;
     if (!(s->state & SOCKET_PRESENT))
-       return CS_NO_CARD;
+       return -ENODEV;
     tuple->TupleLink = tuple->Flags = 0;
 #ifdef CONFIG_CARDBUS
     if (s->state & SOCKET_CARDBUS) {
@@ -444,7 +451,7 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
        if (pccard_get_next_tuple(s, function, tuple) == 0) {
            tuple->DesiredTuple = CISTPL_LINKTARGET;
            if (pccard_get_next_tuple(s, function, tuple) != 0)
-               return CS_NO_MORE_ITEMS;
+               return -ENOSPC;
        } else
            tuple->CISOffset = tuple->TupleLink = 0;
        tuple->DesiredTuple = req;
@@ -499,9 +506,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
     int ofs, i, attr;
 
     if (!s)
-       return CS_BAD_HANDLE;
+       return -EINVAL;
     if (!(s->state & SOCKET_PRESENT))
-       return CS_NO_CARD;
+       return -ENODEV;
 
     link[1] = tuple->TupleLink;
     ofs = tuple->CISOffset + tuple->TupleLink;
@@ -520,7 +527,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
        /* End of chain?  Follow long link if possible */
        if (link[0] == CISTPL_END) {
            if ((ofs = follow_link(s, tuple)) < 0)
-               return CS_NO_MORE_ITEMS;
+               return -ENOSPC;
            attr = SPACE(tuple->Flags);
            read_cis_cache(s, attr, ofs, 2, link);
        }
@@ -578,7 +585,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
     }
     if (i == MAX_TUPLES) {
        cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
-       return CS_NO_MORE_ITEMS;
+       return -ENOSPC;
     }
     
     tuple->TupleCode = link[0];
@@ -597,10 +604,10 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
     u_int len;
 
     if (!s)
-       return CS_BAD_HANDLE;
+       return -EINVAL;
 
     if (tuple->TupleLink < tuple->TupleOffset)
-       return CS_NO_MORE_ITEMS;
+       return -ENOSPC;
     len = tuple->TupleLink - tuple->TupleOffset;
     tuple->TupleDataLen = tuple->TupleLink;
     if (len == 0)
@@ -641,22 +648,28 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device)
        case 3: device->dev[i].speed = 150; break;
        case 4: device->dev[i].speed = 100; break;
        case 7:
-           if (++p == q) return CS_BAD_TUPLE;
+           if (++p == q)
+                   return -EINVAL;
            device->dev[i].speed = SPEED_CVT(*p);
            while (*p & 0x80)
-               if (++p == q) return CS_BAD_TUPLE;
+               if (++p == q)
+                       return -EINVAL;
            break;
        default:
-           return CS_BAD_TUPLE;
+           return -EINVAL;
        }
 
-       if (++p == q) return CS_BAD_TUPLE;
-       if (*p == 0xff) break;
+       if (++p == q)
+               return -EINVAL;
+       if (*p == 0xff)
+               break;
        scale = *p & 7;
-       if (scale == 7) return CS_BAD_TUPLE;
+       if (scale == 7)
+               return -EINVAL;
        device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
        device->ndev++;
-       if (++p == q) break;
+       if (++p == q)
+               break;
     }
     
     return 0;
@@ -668,7 +681,7 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
 {
     u_char *p;
     if (tuple->TupleDataLen < 5)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     p = (u_char *) tuple->TupleData;
     csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
     csum->len = get_unaligned_le16(p + 2);
@@ -681,7 +694,7 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
 {
     if (tuple->TupleDataLen < 4)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     link->addr = get_unaligned_le32(tuple->TupleData);
     return 0;
 }
@@ -698,7 +711,7 @@ static int parse_longlink_mfc(tuple_t *tuple,
     
     link->nfn = *p; p++;
     if (tuple->TupleDataLen <= link->nfn*5)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     for (i = 0; i < link->nfn; i++) {
        link->fn[i].space = *p; p++;
        link->fn[i].addr = get_unaligned_le32(p);
@@ -714,16 +727,19 @@ static int parse_strings(u_char *p, u_char *q, int max,
 {
     int i, j, ns;
 
-    if (p == q) return CS_BAD_TUPLE;
+    if (p == q)
+           return -EINVAL;
     ns = 0; j = 0;
     for (i = 0; i < max; i++) {
-       if (*p == 0xff) break;
+       if (*p == 0xff)
+               break;
        ofs[i] = j;
        ns++;
        for (;;) {
            s[j++] = (*p == 0xff) ? '\0' : *p;
            if ((*p == '\0') || (*p == 0xff)) break;
-           if (++p == q) return CS_BAD_TUPLE;
+           if (++p == q)
+                   return -EINVAL;
        }
        if ((*p == 0xff) || (++p == q)) break;
     }
@@ -731,7 +747,7 @@ static int parse_strings(u_char *p, u_char *q, int max,
        *found = ns;
        return 0;
     } else {
-       return (ns == max) ? 0 : CS_BAD_TUPLE;
+       return (ns == max) ? 0 : -EINVAL;
     }
 }
 
@@ -746,7 +762,8 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
     
     vers_1->major = *p; p++;
     vers_1->minor = *p; p++;
-    if (p >= q) return CS_BAD_TUPLE;
+    if (p >= q)
+           return -EINVAL;
 
     return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
                         vers_1->str, vers_1->ofs, &vers_1->ns);
@@ -790,7 +807,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
     if (tuple->TupleDataLen < 4)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     m->manf = get_unaligned_le16(tuple->TupleData);
     m->card = get_unaligned_le16(tuple->TupleData + 2);
     return 0;
@@ -802,7 +819,7 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
 {
     u_char *p;
     if (tuple->TupleDataLen < 2)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     p = (u_char *)tuple->TupleData;
     f->func = p[0];
     f->sysinit = p[1];
@@ -816,7 +833,7 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
     u_char *p;
     int i;
     if (tuple->TupleDataLen < 1)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     p = (u_char *)tuple->TupleData;
     f->type = p[0];
     for (i = 1; i < tuple->TupleDataLen; i++)
@@ -835,7 +852,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config)
     rasz = *p & 0x03;
     rmsz = (*p & 0x3c) >> 2;
     if (tuple->TupleDataLen < rasz+rmsz+4)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     config->last_idx = *(++p);
     p++;
     config->base = 0;
@@ -1003,10 +1020,12 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
 
 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
 {
-    if (p == q) return NULL;
+    if (p == q)
+           return NULL;
     irq->IRQInfo1 = *p; p++;
     if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
-       if (p+2 > q) return NULL;
+       if (p+2 > q)
+               return NULL;
        irq->IRQInfo2 = (p[1]<<8) + p[0];
        p += 2;
     }
@@ -1027,7 +1046,8 @@ static int parse_cftable_entry(tuple_t *tuple,
     if (*p & 0x40)
        entry->flags |= CISTPL_CFTABLE_DEFAULT;
     if (*p & 0x80) {
-       if (++p == q) return CS_BAD_TUPLE;
+       if (++p == q)
+               return -EINVAL;
        if (*p & 0x10)
            entry->flags |= CISTPL_CFTABLE_BVDS;
        if (*p & 0x20)
@@ -1041,30 +1061,35 @@ static int parse_cftable_entry(tuple_t *tuple,
        entry->interface = 0;
 
     /* Process optional features */
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+           return -EINVAL;
     features = *p; p++;
 
     /* Power options */
     if ((features & 3) > 0) {
        p = parse_power(p, q, &entry->vcc);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vcc.present = 0;
     if ((features & 3) > 1) {
        p = parse_power(p, q, &entry->vpp1);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vpp1.present = 0;
     if ((features & 3) > 2) {
        p = parse_power(p, q, &entry->vpp2);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vpp2.present = 0;
 
     /* Timing options */
     if (features & 0x04) {
        p = parse_timing(p, q, &entry->timing);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else {
        entry->timing.wait = 0;
        entry->timing.ready = 0;
@@ -1074,14 +1099,16 @@ static int parse_cftable_entry(tuple_t *tuple,
     /* I/O window options */
     if (features & 0x08) {
        p = parse_io(p, q, &entry->io);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->io.nwin = 0;
     
     /* Interrupt options */
     if (features & 0x10) {
        p = parse_irq(p, q, &entry->irq);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->irq.IRQInfo1 = 0;
 
@@ -1095,7 +1122,8 @@ static int parse_cftable_entry(tuple_t *tuple,
        entry->mem.win[0].card_addr = 0;
        entry->mem.win[0].host_addr = 0;
        p += 2;
-       if (p > q) return CS_BAD_TUPLE;
+       if (p > q)
+               return -EINVAL;
        break;
     case 0x40:
        entry->mem.nwin = 1;
@@ -1103,20 +1131,24 @@ static int parse_cftable_entry(tuple_t *tuple,
        entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
        entry->mem.win[0].host_addr = 0;
        p += 4;
-       if (p > q) return CS_BAD_TUPLE;
+       if (p > q)
+               return -EINVAL;
        break;
     case 0x60:
        p = parse_mem(p, q, &entry->mem);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
        break;
     }
 
     /* Misc features */
     if (features & 0x80) {
-       if (p == q) return CS_BAD_TUPLE;
+       if (p == q)
+               return -EINVAL;
        entry->flags |= (*p << 8);
        while (*p & 0x80)
-           if (++p == q) return CS_BAD_TUPLE;
+           if (++p == q)
+                   return -EINVAL;
        p++;
     }
 
@@ -1133,7 +1165,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
 {
     u_char *p;
     if (tuple->TupleDataLen < 6)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     p = (u_char *)tuple->TupleData;
     bar->attr = *p;
     p += 2;
@@ -1147,7 +1179,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
     
     p = (u_char *)tuple->TupleData;
     if ((*p != 3) || (tuple->TupleDataLen < 6))
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     config->last_idx = *(++p);
     p++;
     config->base = get_unaligned_le32(p);
@@ -1168,29 +1200,34 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
        entry->flags |= CISTPL_CFTABLE_DEFAULT;
 
     /* Process optional features */
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+           return -EINVAL;
     features = *p; p++;
 
     /* Power options */
     if ((features & 3) > 0) {
        p = parse_power(p, q, &entry->vcc);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vcc.present = 0;
     if ((features & 3) > 1) {
        p = parse_power(p, q, &entry->vpp1);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vpp1.present = 0;
     if ((features & 3) > 2) {
        p = parse_power(p, q, &entry->vpp2);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->vpp2.present = 0;
 
     /* I/O window options */
     if (features & 0x08) {
-       if (p == q) return CS_BAD_TUPLE;
+       if (p == q)
+               return -EINVAL;
        entry->io = *p; p++;
     } else
        entry->io = 0;
@@ -1198,26 +1235,31 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
     /* Interrupt options */
     if (features & 0x10) {
        p = parse_irq(p, q, &entry->irq);
-       if (p == NULL) return CS_BAD_TUPLE;
+       if (p == NULL)
+               return -EINVAL;
     } else
        entry->irq.IRQInfo1 = 0;
 
     if (features & 0x20) {
-       if (p == q) return CS_BAD_TUPLE;
+       if (p == q)
+               return -EINVAL;
        entry->mem = *p; p++;
     } else
        entry->mem = 0;
 
     /* Misc features */
     if (features & 0x80) {
-       if (p == q) return CS_BAD_TUPLE;
+       if (p == q)
+               return -EINVAL;
        entry->flags |= (*p << 8);
        if (*p & 0x80) {
-           if (++p == q) return CS_BAD_TUPLE;
+           if (++p == q)
+                   return -EINVAL;
            entry->flags |= (*p << 16);
        }
        while (*p & 0x80)
-           if (++p == q) return CS_BAD_TUPLE;
+           if (++p == q)
+                   return -EINVAL;
        p++;
     }
 
@@ -1259,7 +1301,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
     u_char *p, *q;
 
     if (tuple->TupleDataLen < 10)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
@@ -1283,13 +1325,16 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org)
     
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
-    if (p == q) return CS_BAD_TUPLE;
+    if (p == q)
+           return -EINVAL;
     org->data_org = *p;
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+           return -EINVAL;
     for (i = 0; i < 30; i++) {
        org->desc[i] = *p;
        if (*p == '\0') break;
-       if (++p == q) return CS_BAD_TUPLE;
+       if (++p == q)
+               return -EINVAL;
     }
     return 0;
 }
@@ -1301,7 +1346,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
     u_char *p;
 
     if (tuple->TupleDataLen < 10)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
 
     p = tuple->TupleData;
 
@@ -1315,12 +1360,12 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
 
 /*====================================================================*/
 
-int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
 {
     int ret = 0;
     
     if (tuple->TupleDataLen > tuple->TupleDataMax)
-       return CS_BAD_TUPLE;
+       return -EINVAL;
     switch (tuple->TupleCode) {
     case CISTPL_DEVICE:
     case CISTPL_DEVICE_A:
@@ -1391,12 +1436,14 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
        ret = 0;
        break;
     default:
-       ret = CS_UNSUPPORTED_FUNCTION;
+       ret = -EINVAL;
        break;
     }
+    if (ret)
+           __cs_dbg(0, "parse_tuple failed %d\n", ret);
     return ret;
 }
-EXPORT_SYMBOL(pccard_parse_tuple);
+EXPORT_SYMBOL(pcmcia_parse_tuple);
 
 /*======================================================================
 
@@ -1411,8 +1458,10 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
     int ret;
 
     buf = kmalloc(256, GFP_KERNEL);
-    if (buf == NULL)
-       return CS_OUT_OF_RESOURCE;
+    if (buf == NULL) {
+           dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+           return -ENOMEM;
+    }
     tuple.DesiredTuple = code;
     tuple.Attributes = TUPLE_RETURN_COMMON;
     ret = pccard_get_first_tuple(s, function, &tuple);
@@ -1424,7 +1473,7 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
     ret = pccard_get_tuple_data(s, &tuple);
     if (ret != 0)
            goto done;
-    ret = pccard_parse_tuple(&tuple, parse);
+    ret = pcmcia_parse_tuple(&tuple, parse);
 done:
     kfree(buf);
     return ret;
@@ -1449,15 +1498,18 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
     int ret, reserved, dev_ok = 0, ident_ok = 0;
 
     if (!s)
-       return CS_BAD_HANDLE;
+       return -EINVAL;
 
     tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
-    if (tuple == NULL)
-       return CS_OUT_OF_RESOURCE;
+    if (tuple == NULL) {
+           dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+           return -ENOMEM;
+    }
     p = kmalloc(sizeof(*p), GFP_KERNEL);
     if (p == NULL) {
-       kfree(tuple);
-       return CS_OUT_OF_RESOURCE;
+           kfree(tuple);
+           dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+           return -ENOMEM;
     }
 
     count = reserved = 0;
@@ -1479,7 +1531,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
        cards have only a broken VERS_2 tuple; hence the bogus test. */
     if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
        (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
-       (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
+       (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
        ident_ok++;
 
     if (!dev_ok && !ident_ok)