V4L/DVB: media/az6027: handle -EIO failure
[safe/jmp/linux-2.6] / drivers / media / dvb / dvb-usb / az6027.c
index 7db7d3d..6681ac1 100644 (file)
@@ -125,12 +125,12 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
        { STB0899_RCOMPC                , 0xc9 },
        { STB0899_AGC1CN                , 0x01 },
        { STB0899_AGC1REF               , 0x10 },
-       { STB0899_RTC                   , 0x23 },
+       { STB0899_RTC                   , 0x23 },
        { STB0899_TMGCFG                , 0x4e },
        { STB0899_AGC2REF               , 0x34 },
        { STB0899_TLSR                  , 0x84 },
        { STB0899_CFD                   , 0xf7 },
-       { STB0899_ACLC                  , 0x87 },
+       { STB0899_ACLC                  , 0x87 },
        { STB0899_BCLC                  , 0x94 },
        { STB0899_EQON                  , 0x41 },
        { STB0899_LDT                   , 0xf1 },
@@ -183,10 +183,10 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
        { STB0899_ECNT3M                , 0x0a },
        { STB0899_ECNT3L                , 0xad },
        { STB0899_FECAUTO1              , 0x06 },
-       { STB0899_FECM                  , 0x01 },
+       { STB0899_FECM                  , 0x01 },
        { STB0899_VTH12                 , 0xb0 },
        { STB0899_VTH23                 , 0x7a },
-       { STB0899_VTH34                 , 0x58 },
+       { STB0899_VTH34                 , 0x58 },
        { STB0899_VTH56                 , 0x38 },
        { STB0899_VTH67                 , 0x34 },
        { STB0899_VTH78                 , 0x24 },
@@ -195,7 +195,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
        { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
        { STB0899_TSULC                 , 0x42 },
        { STB0899_RSLLC                 , 0x41 },
-       { STB0899_TSLPL                 , 0x12 },
+       { STB0899_TSLPL                 , 0x12 },
        { STB0899_TSCFGH                , 0x0c },
        { STB0899_TSCFGM                , 0x00 },
        { STB0899_TSCFGL                , 0x00 },
@@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 }
 
 /* keys for the enclosed remote control */
-static struct dvb_usb_rc_key az6027_rc_keys[] = {
+static struct dvb_usb_rc_key ir_codes_az6027_table[] = {
        { 0x01, KEY_1 },
        { 0x02, KEY_2 },
 };
@@ -417,11 +417,15 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
        u16 value;
        u16 index;
        int blen;
-       u8 b[12];
+       u8 *b;
 
        if (slot != 0)
                return -EINVAL;
 
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
        mutex_lock(&state->ca_mutex);
 
        req = 0xC1;
@@ -438,6 +442,7 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
        }
 
        mutex_unlock(&state->ca_mutex);
+       kfree(b);
        return ret;
 }
 
@@ -485,11 +490,15 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
        u16 value;
        u16 index;
        int blen;
-       u8 b[12];
+       u8 *b;
 
        if (slot != 0)
                return -EINVAL;
 
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
        mutex_lock(&state->ca_mutex);
 
        req = 0xC3;
@@ -510,6 +519,7 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
        }
 
        mutex_unlock(&state->ca_mutex);
+       kfree(b);
        return ret;
 }
 
@@ -556,7 +566,11 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
        u16 value;
        u16 index;
        int blen;
-       u8 b[12];
+       u8 *b;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
 
        req = 0xC8;
        value = 0;
@@ -570,6 +584,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
        } else{
                ret = b[0];
        }
+       kfree(b);
        return ret;
 }
 
@@ -667,8 +682,11 @@ static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int o
        u16 value;
        u16 index;
        int blen;
-       u8 b[12];
+       u8 *b;
 
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
        mutex_lock(&state->ca_mutex);
 
        req = 0xC5;
@@ -683,15 +701,13 @@ static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int o
        } else
                ret = 0;
 
-       if (b[0] == 0) {
-               ret = 0;
-
-       } else if (b[0] == 1) {
+       if (!ret && b[0] == 1) {
                ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
                      DVB_CA_EN50221_POLL_CAM_READY;
        }
 
        mutex_unlock(&state->ca_mutex);
+       kfree(b);
        return ret;
 }
 
@@ -943,10 +959,16 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
        u16 value;
        int length;
        u8 req;
-       u8 data[256];
+       u8 *data;
+
+       data = kmalloc(256, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
+               kfree(data);
                return -EAGAIN;
+       }
 
        if (num > 2)
                warn("more than 2 i2c messages at a time is not handled yet. TODO.");
@@ -1016,6 +1038,7 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
                }
        }
        mutex_unlock(&d->i2c_mutex);
+       kfree(data);
 
        return i;
 }
@@ -1036,8 +1059,14 @@ int az6027_identify_state(struct usb_device *udev,
                          struct dvb_usb_device_description **desc,
                          int *cold)
 {
-       u8 b[16];
-       s16 ret = usb_control_msg(udev,
+       u8 *b;
+       s16 ret;
+
+       b = kmalloc(16, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       ret = usb_control_msg(udev,
                                  usb_rcvctrlpipe(udev, 0),
                                  0xb7,
                                  USB_TYPE_VENDOR | USB_DIR_IN,
@@ -1048,7 +1077,7 @@ int az6027_identify_state(struct usb_device *udev,
                                  USB_CTRL_GET_TIMEOUT);
 
        *cold = ret <= 0;
-
+       kfree(b);
        deb_info("cold: %d\n", *cold);
        return 0;
 }
@@ -1056,7 +1085,8 @@ int az6027_identify_state(struct usb_device *udev,
 
 static struct usb_device_id az6027_usb_table[] = {
        { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V1) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V2) },
        { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
        { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
        { },
@@ -1095,18 +1125,34 @@ static struct dvb_usb_device_properties az6027_properties = {
        .power_ctrl       = az6027_power_ctrl,
        .read_mac_address = az6027_read_mac_addr,
  */
-       .rc_key_map       = az6027_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(az6027_rc_keys),
+       .rc_key_map       = ir_codes_az6027_table,
+       .rc_key_map_size  = ARRAY_SIZE(ir_codes_az6027_table),
        .rc_interval      = 400,
        .rc_query         = az6027_rc_query,
        .i2c_algo         = &az6027_i2c_algo,
 
-       .num_device_descs = 1,
+       .num_device_descs = 5,
        .devices = {
                {
                        .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
                        .cold_ids = { &az6027_usb_table[0], NULL },
                        .warm_ids = { NULL },
+               }, {
+                       .name = "TERRATEC S7",
+                       .cold_ids = { &az6027_usb_table[1], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "TERRATEC S7 MKII",
+                       .cold_ids = { &az6027_usb_table[2], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "Technisat SkyStar USB 2 HD CI",
+                       .cold_ids = { &az6027_usb_table[3], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "Technisat SkyStar USB 2 HD CI",
+                       .cold_ids = { &az6027_usb_table[4], NULL },
+                       .warm_ids = { NULL },
                },
                { NULL },
        }