diff options
58 files changed, 1110 insertions, 1486 deletions
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 8eaa88fd8b9..9a8dd8764c9 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/string.h> +#include <linux/jiffies.h> #include <media/ir-common.h> /* -------------------------------------------------------------------------- */ diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index ebf4dc5190f..76e9c36597e 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -605,7 +605,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) { &utype, sizeof utype }, { priv->ule_skb->data, priv->ule_skb->len - 4 } }; - unsigned long ule_crc = ~0L, expected_crc; + u32 ule_crc = ~0L, expected_crc; if (priv->ule_dbit) { /* Set D-bit for CRC32 verification, * if it was set originally. */ @@ -618,7 +618,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) *((u8 *)priv->ule_skb->tail - 2) << 8 | *((u8 *)priv->ule_skb->tail - 1); if (ule_crc != expected_crc) { - printk(KERN_WARNING "%lu: CRC32 check FAILED: %#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", + printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0); #ifdef ULE_DEBUG diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index d48622e76b1..badc468170e 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -90,9 +90,11 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle); for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) { - deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); if (haupp_rc_keys[i].data == data && haupp_rc_keys[i].custom == custom) { + + deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); + *event = haupp_rc_keys[i].event; *state = REMOTE_KEY_PRESSED; if (st->old_toggle == toggle) { diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 5da66178006..23aa75a27c1 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -515,7 +515,7 @@ static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2; fchan.vit_hrch = 0; fchan.vit_select_hp = 1; - dib3000mc_set_channel_cfg(state, &fchan, 7); + dib3000mc_set_channel_cfg(state, &fchan, 11); reg = dib3000mc_read_word(state, 0); dib3000mc_write_word(state, 0, reg | (1 << 8)); diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 29a11c1db1b..57357db31b8 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -668,7 +668,7 @@ config VIDEO_M32R_AR_M64278 config VIDEO_CAFE_CCIC tristate "Marvell 88ALP01 (Cafe) CMOS Camera Controller support" - depends on I2C && VIDEO_V4L2 + depends on PCI && I2C && VIDEO_V4L2 select VIDEO_OV7670 ---help--- This is a video4linux2 driver for the Marvell 88ALP01 integrated diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 3c8e4742dcc..ab8f970760f 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4050,8 +4050,8 @@ static int __devinit bttv_probe(struct pci_dev *dev, (unsigned long long)pci_resource_start(dev,0)); schedule(); - btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); - if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) { + btv->bt848_mmio = ioremap(pci_resource_start(dev, 0), 0x1000); + if (NULL == btv->bt848_mmio) { printk("bttv%d: ioremap() failed\n", btv->c.nr); result = -EIO; goto fail1; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index e347c7ebc98..3083c8075d1 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2166,7 +2166,7 @@ static void cafe_pci_remove(struct pci_dev *pdev) struct cafe_camera *cam = cafe_find_by_pdev(pdev); if (cam == NULL) { - cam_warn(cam, "pci_remove on unknown pdev %p\n", pdev); + printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev); return; } mutex_lock(&cam->s_mutex); diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c index 28dc6a1a1e4..d8e929863a8 100644 --- a/drivers/media/video/cpia2/cpia2_usb.c +++ b/drivers/media/video/cpia2/cpia2_usb.c @@ -640,6 +640,10 @@ static int submit_urbs(struct camera_data *cam) cam->sbuf[i].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); if (!cam->sbuf[i].data) { + while (--i >= 0) { + kfree(cam->sbuf[i].data); + cam->sbuf[i].data = NULL; + } return -ENOMEM; } } diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 657e0b96914..2f5ca71e026 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -742,7 +742,6 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func, if (old == NULL || old->width != new->width || old->height != new->height || old->video_encoding != new->video_encoding) { - int is_scaling; u16 w = new->width; u16 h = new->height; @@ -752,20 +751,18 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func, } err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w); if (err) return err; + } + if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) { /* Adjust temporal filter if necessary. The problem with the temporal filter is that it works well with full resolution capturing, but not when the capture window is scaled (the filter introduces - a ghosting effect). So if the capture window changed, and there is - no updated filter value, then the filter is set depending on whether - the new window is full resolution or not. + a ghosting effect). So if the capture window is scaled, then + force the filter to 0. - For full resolution a setting of 8 really improves the video + For full resolution the filter really improves the video quality, especially if the original video quality is suboptimal. */ - is_scaling = new->width != 720 || new->height != (new->is_50hz ? 576 : 480); - if (old && old->video_temporal_filter == temporal) { - temporal = is_scaling ? 0 : 8; - } + temporal = 0; } if (old == NULL || old->stream_type != new->stream_type) { @@ -866,6 +863,7 @@ invalid: void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) { int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; + int temporal = p->video_temporal_filter; /* Stream */ printk(KERN_INFO "%s: Stream: %s\n", @@ -922,10 +920,13 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), p->video_spatial_filter); + if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) { + temporal = 0; + } printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), - p->video_temporal_filter); + temporal); printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index f85f2084324..ced13febed8 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c @@ -128,7 +128,14 @@ void cx25840_vbi_setup(struct i2c_client *client) uv_lpf=1; src_decimation=0x21f; - if (std == V4L2_STD_PAL_M) { + if (std == V4L2_STD_PAL_60) { + vblank=26; + vblank656=26; + burst=0x5b; + luma_lpf=2; + comb=0x20; + sc=0x0a8263; + } else if (std == V4L2_STD_PAL_M) { vblank=20; vblank656=24; burst=0x61; diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index c791708b133..434b78ab37d 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -1632,7 +1632,7 @@ const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); /* ----------------------------------------------------------------------- */ /* some leadtek specific stuff */ -static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) +static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) { /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on * any others. diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 453af5e943f..18997361c75 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -633,12 +633,12 @@ int cx88_reset(struct cx88_core *core) static unsigned int inline norm_swidth(struct cx88_tvnorm *norm) { - return (norm->id & V4L2_STD_625_50) ? 922 : 754; + return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; } static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm) { - return (norm->id & V4L2_STD_625_50) ? 186 : 135; + return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186; } static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm) @@ -648,24 +648,33 @@ static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm) static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm) { - static const unsigned int ntsc = 28636360; - static const unsigned int pal = 35468950; - static const unsigned int palm = 28604892; - if (norm->id & V4L2_STD_PAL_M) - return palm; + return 28604892; // 3.575611 MHz + + if (norm->id & (V4L2_STD_PAL_Nc)) + return 28656448; // 3.582056 MHz + + if (norm->id & V4L2_STD_NTSC) // All NTSC/M and variants + return 28636360; // 3.57954545 MHz +/- 10 Hz - return (norm->id & V4L2_STD_625_50) ? pal : ntsc; + /* SECAM have also different sub carrier for chroma, + but step_db and step_dr, at cx88_set_tvnorm already handles that. + + The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N + */ + + return 35468950; // 4.43361875 MHz +/- 5 Hz } static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) { - /* Should always be Line Draw Time / (4*FSC) */ - if (norm->id & V4L2_STD_PAL_M) - return 909; + unsigned int fsc4=norm_fsc8(norm)/2; - return (norm->id & V4L2_STD_625_50) ? 1135 : 910; + /* returns 4*FSC / vtotal / frames per seconds */ + return (norm->id & V4L2_STD_625_50) ? + ((fsc4+312)/625+12)/25 : + ((fsc4+262)/525*1001+15000)/30000; } static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) @@ -692,7 +701,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig value &= 0x3fe; cx_write(MO_HDELAY_EVEN, value); cx_write(MO_HDELAY_ODD, value); - dprintk(1,"set_scale: hdelay 0x%04x\n", value); + dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth); value = (swidth * 4096 / width) - 4096; cx_write(MO_HSCALE_EVEN, value); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 7054e941f1d..a9575ad8ca2 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -91,7 +91,7 @@ struct cx88_tvnorm { static unsigned int inline norm_maxw(struct cx88_tvnorm *norm) { - return (norm->id & V4L2_STD_625_50) ? 768 : 640; + return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; } diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2a461dde480..36e72c207a8 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1674,9 +1674,9 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, if (dev->has_msp34xx) { /* Send a reset to other chips via gpio */ em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); - udelay(2500); + msleep(3); em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); - udelay(2500); + msleep(3); } video_mux(dev, 0); diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index b083338823d..616a35da191 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -923,7 +923,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, struct video_picture *p = arg; if (p->depth != 16) return -EINVAL; - if (p->palette != VIDEO_PALETTE_YUV422) + if (p->palette != VIDEO_PALETTE_YUV422 && p->palette != VIDEO_PALETTE_YUYV) return -EINVAL; mutex_lock(&meye.lock); sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, @@ -978,7 +978,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (vm->frame >= gbuffers || vm->frame < 0) return -EINVAL; - if (vm->format != VIDEO_PALETTE_YUV422) + if (vm->format != VIDEO_PALETTE_YUV422 && vm->format != VIDEO_PALETTE_YUYV) return -EINVAL; if (vm->height * vm->width * 2 > gbufsize) return -EINVAL; diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index e1b56dc13c3..2fb9fe6a1ae 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -633,10 +633,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) if (((rt->input >> (4 + i * 4)) & 0xf) == 0) extern_input = 0; } - if (extern_input) - state->mode = MSP_MODE_EXTERN; - else - state->mode = MSP_MODE_AM_DETECT; + state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT; + state->rxsubchans = V4L2_TUNER_SUB_STEREO; msp_set_scart(client, sc_in, 0); msp_set_scart(client, sc1_out, 1); msp_set_scart(client, sc2_out, 2); @@ -951,7 +949,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) if (thread_func) { state->kthread = kthread_run(thread_func, client, "msp34xx"); - if (state->kthread == NULL) + if (IS_ERR(state->kthread)) v4l_warn(client, "kernel_thread() failed\n"); msp_wake_thread(client); } diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 4c7f85b566a..e1821eb82fb 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -483,7 +483,6 @@ int msp3400c_thread(void *data) /* no carrier scan, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); state->scan_in_progress = 0; - state->rxsubchans = V4L2_TUNER_SUB_STEREO; msp_set_audio(client); continue; } @@ -851,12 +850,15 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) source = 1; /* stereo or A|B */ matrix = 0x20; break; - case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1: - default: source = 3; /* stereo or A */ matrix = 0x00; break; + case V4L2_TUNER_MODE_STEREO: + default: + source = 3; /* stereo or A */ + matrix = 0x20; + break; } if (in == MSP_DSP_IN_TUNER) @@ -1030,6 +1032,9 @@ static int msp34xxg_detect_stereo(struct i2c_client *client) int is_stereo = status & 0x40; int oldrx = state->rxsubchans; + if (state->mode == MSP_MODE_EXTERN) + return 0; + state->rxsubchans = 0; if (is_stereo) state->rxsubchans = V4L2_TUNER_SUB_STEREO; diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index fa833987909..c33f6a69a24 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -50,9 +50,9 @@ static unsigned int antenna_pwr = 0; module_param(antenna_pwr, int, 0444); MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)"); -static int use_frontent = 0; -module_param(use_frontent, int, 0644); -MODULE_PARM_DESC(use_frontent,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); +static int use_frontend = 0; +module_param(use_frontend, int, 0644); +MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); /* ------------------------------------------------------------------ */ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) @@ -1303,7 +1303,7 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_FLYDVB_TRIO: - if(! use_frontent) { //terrestrial + if(! use_frontend) { //terrestrial dev->dvb.frontend = dvb_attach(tda10046_attach, &lifeview_trio_config, &dev->i2c_adap); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 705daaa2a4f..ee4a493032d 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -267,6 +267,10 @@ static int tuner_fixup_std(struct tuner *t) { if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { switch (pal[0]) { + case '6': + tuner_dbg ("insmod fixup: PAL => PAL-60\n"); + t->std = V4L2_STD_PAL_60; + break; case 'b': case 'B': case 'g': diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c index 134eb9865df..a40e5838515 100644 --- a/drivers/media/video/usbvision/usbvision-cards.c +++ b/drivers/media/video/usbvision/usbvision-cards.c @@ -39,8 +39,8 @@ struct usbvision_device_data_st usbvision_device_data[] = { {0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"}, {0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"}, {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Osprey 50"}, - {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"}, - {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"}, + {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"}, + {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"}, {0x0573, 0x4100, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Nogatech USB-TV (NTSC) FM"}, {0x0573, 0x4110, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "PNY USB-TV (NTSC) FM"}, {0x0573, 0x4450, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "PixelView PlayTv-USB PRO (PAL) FM"}, @@ -71,10 +71,10 @@ struct usbvision_device_data_st usbvision_device_data[] = { {0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB device Model 40219 Rev E189"}, {0x0768, 0x0006, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 5, 5, -1, "Camtel Technology USB TV Genie Pro FM Model TVB330"}, {0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"}, - {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"}, + {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"}, {0x07d0, 0x0003, 0, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)"}, {0x07d0, 0x0004, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-80 Rev 1 (PAL)"}, - {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"}, + {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"}, {0x2304, 0x010d, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 0, 1, TUNER_TEMIC_4066FY5_PAL_I, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (PAL)"}, {0x2304, 0x0109, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (SECAM)"}, {0x2304, 0x0110, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1,128, 23, -1, "Pinnacle Studio PCTV USB (PAL) FM"}, @@ -86,7 +86,7 @@ struct usbvision_device_data_st usbvision_device_data[] = { {0x2304, 0x0300, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (NTSC)"}, {0x2304, 0x0301, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (PAL)"}, {0x2304, 0x0419, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle PCTV Bungee USB (PAL) FM"}, - {0x2400, 0x4200, -1, CODEC_SAA7111, 3, VIDEO_MODE_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"}, + {0x2400, 0x4200, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"}, {} /* Terminating entry */ }; @@ -148,7 +148,6 @@ struct usb_device_id usbvision_table [] = { { USB_DEVICE(0x2304, 0x0300) }, /* Pinnacle Studio Linx Video input cable (NTSC) */ { USB_DEVICE(0x2304, 0x0301) }, /* Pinnacle Studio Linx Video input cable (PAL) */ { USB_DEVICE(0x2304, 0x0419) }, /* Pinnacle PCTV Bungee USB (PAL) FM */ - { USB_DEVICE(0x2400, 0x4200) }, /* Hauppauge WinTv-USB2 Model 42012 */ { } /* Terminating entry */ diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 797b97baf9e..a807d971e27 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c @@ -118,7 +118,7 @@ static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision); * This is used when initializing the contents of the area. */ -void *usbvision_rvmalloc(unsigned long size) +static void *usbvision_rvmalloc(unsigned long size) { void *mem; unsigned long adr; @@ -181,7 +181,7 @@ static void usbvision_hexdump(const unsigned char *data, int len) /******************************** * scratch ring buffer handling ********************************/ -int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */ +static int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */ { int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr; if (len < 0) { @@ -194,7 +194,7 @@ int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of /* This returns the free space left in the buffer */ -int scratch_free(struct usb_usbvision *usbvision) +static int scratch_free(struct usb_usbvision *usbvision) { int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr; if (free <= 0) { @@ -211,7 +211,8 @@ int scratch_free(struct usb_usbvision *usbvision) /* This puts data into the buffer */ -int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, int len) +static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, + int len) { int len_part; @@ -237,7 +238,7 @@ int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, int len) } /* This marks the write_ptr as position of new frame header */ -void scratch_mark_header(struct usb_usbvision *usbvision) +static void scratch_mark_header(struct usb_usbvision *usbvision) { PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr); @@ -248,7 +249,8 @@ void scratch_mark_header(struct usb_usbvision *usbvision) } /* This gets data from the buffer at the given "ptr" position */ -int scratch_get_extra(struct usb_usbvision *usbvision, unsigned char *data, int *ptr, int len) +static int scratch_get_extra(struct usb_usbvision *usbvision, + unsigned char *data, int *ptr, int len) { int len_part; if (*ptr + len < scratch_buf_size) { @@ -274,7 +276,8 @@ int scratch_get_extra(struct usb_usbvision *usbvision, unsigned char *data, int /* This sets the scratch extra read pointer */ -void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, int len) +static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, + int len) { *ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size; @@ -283,7 +286,7 @@ void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, int len) /*This increments the scratch extra read pointer */ -void scratch_inc_extra_ptr(int *ptr, int len) +static void scratch_inc_extra_ptr(int *ptr, int len) { *ptr = (*ptr + len) % scratch_buf_size; @@ -292,7 +295,8 @@ void scratch_inc_extra_ptr(int *ptr, int len) /* This gets data from the buffer */ -int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, int len) +static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, + int len) { int len_part; if (usbvision->scratch_read_ptr + len < scratch_buf_size) { @@ -318,7 +322,8 @@ int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, int len) /* This sets read pointer to next header and returns it */ -int scratch_get_header(struct usb_usbvision *usbvision,struct usbvision_frame_header *header) +static int scratch_get_header(struct usb_usbvision *usbvision, + struct usbvision_frame_header *header) { int errCode = 0; @@ -346,7 +351,7 @@ int scratch_get_header(struct usb_usbvision *usbvision,struct usbvision_frame_he /*This removes len bytes of old data from the buffer */ -void scratch_rm_old(struct usb_usbvision *usbvision, int len) +static void scratch_rm_old(struct usb_usbvision *usbvision, int len) { usbvision->scratch_read_ptr += len; @@ -356,7 +361,7 @@ void scratch_rm_old(struct usb_usbvision *usbvision, int len) /*This resets the buffer - kills all data in it too */ -void scratch_reset(struct usb_usbvision *usbvision) +static void scratch_reset(struct usb_usbvision *usbvision) { PDEBUG(DBG_SCRATCH, "\n"); @@ -369,7 +374,7 @@ void scratch_reset(struct usb_usbvision *usbvision) int usbvision_scratch_alloc(struct usb_usbvision *usbvision) { - usbvision->scratch = vmalloc(scratch_buf_size); + usbvision->scratch = vmalloc_32(scratch_buf_size); scratch_reset(usbvision); if(usbvision->scratch == NULL) { err("%s: unable to allocate %d bytes for scratch", @@ -399,8 +404,8 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision) * 1: Draw a colored grid * */ -void usbvision_testpattern(struct usb_usbvision *usbvision, int fullframe, - int pmode) +static void usbvision_testpattern(struct usb_usbvision *usbvision, + int fullframe, int pmode) { static const char proc[] = "usbvision_testpattern"; struct usbvision_frame *frame; @@ -480,7 +485,7 @@ void usbvision_testpattern(struct usb_usbvision *usbvision, int fullframe, int usbvision_decompress_alloc(struct usb_usbvision *usbvision) { int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; - usbvision->IntraFrameBuffer = vmalloc(IFB_size); + usbvision->IntraFrameBuffer = vmalloc_32(IFB_size); if (usbvision->IntraFrameBuffer == NULL) { err("%s: unable to allocate %d for compr. frame buffer", __FUNCTION__, IFB_size); return -ENOMEM; @@ -2199,6 +2204,7 @@ int usbvision_power_on(struct usb_usbvision *usbvision) usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN); usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN | USBVISION_RES2); + usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN | USBVISION_PWR_VID); errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG, @@ -2305,7 +2311,7 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision) usbvision->Vin_Reg2_Preset)) < 0) return ret; /* TODO: schedule timeout */ - while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) && 0x01) != 1); + while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1); return 0; } @@ -2346,40 +2352,6 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format) return USBVISION_IS_OPERATIONAL(usbvision); } - -int usbvision_sbuf_alloc(struct usb_usbvision *usbvision) -{ - int i, errCode = 0; - const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; - - /* Clean pointers so we know if we allocated something */ - for (i = 0; i < USBVISION_NUMSBUF; i++) - usbvision->sbuf[i].data = NULL; - - for (i = 0; i < USBVISION_NUMSBUF; i++) { - usbvision->sbuf[i].data = kzalloc(sb_size, GFP_KERNEL); - if (usbvision->sbuf[i].data == NULL) { - err("%s: unable to allocate %d bytes for sbuf", __FUNCTION__, sb_size); - errCode = -ENOMEM; - break; - } - } - return errCode; -} - - -void usbvision_sbuf_free(struct usb_usbvision *usbvision) -{ - int i; - - for (i = 0; i < USBVISION_NUMSBUF; i++) { - if (usbvision->sbuf[i].data != NULL) { - kfree(usbvision->sbuf[i].data); - usbvision->sbuf[i].data = NULL; - } - } -} - /* * usbvision_init_isoc() * @@ -2388,6 +2360,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) { struct usb_device *dev = usbvision->dev; int bufIdx, errCode, regValue; + const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; if (!USBVISION_IS_OPERATIONAL(usbvision)) return -EFAULT; @@ -2423,6 +2396,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) return -ENOMEM; } usbvision->sbuf[bufIdx].urb = urb; + usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma); urb->dev = dev; urb->context = usbvision; urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); @@ -2464,6 +2438,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) void usbvision_stop_isoc(struct usb_usbvision *usbvision) { int bufIdx, errCode, regValue; + const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL)) return; @@ -2471,6 +2446,12 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) /* Unschedule all of the iso td's */ for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { usb_kill_urb(usbvision->sbuf[bufIdx].urb); + if (usbvision->sbuf[bufIdx].data){ + usb_buffer_free(usbvision->dev, + sb_size, + usbvision->sbuf[bufIdx].data, + usbvision->sbuf[bufIdx].urb->transfer_dma); + } usb_free_urb(usbvision->sbuf[bufIdx].urb); usbvision->sbuf[bufIdx].urb = NULL; } diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 0f3fba7ea6f..858252c1508 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -58,7 +58,6 @@ static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, static inline int try_write_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { - struct i2c_algo_usb_data *adap = i2c_adap->algo_data; void *data; int i, ret = -1; char buf[4]; @@ -69,10 +68,10 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap, ret = (usbvision_i2c_write(data, addr, buf, 1)); if (ret == 1) break; /* success! */ - udelay(5 /*adap->udelay */ ); + udelay(5); if (i == retries) /* no success */ break; - udelay(adap->udelay); + udelay(10); } if (i) { PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr); @@ -84,7 +83,6 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap, static inline int try_read_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { - struct i2c_algo_usb_data *adap = i2c_adap->algo_data; void *data; int i, ret = -1; char buf[4]; @@ -94,10 +92,10 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap, ret = (usbvision_i2c_read(data, addr, buf, 1)); if (ret == 1) break; /* success! */ - udelay(5 /*adap->udelay */ ); + udelay(5); if (i == retries) /* no success */ break; - udelay(adap->udelay); + udelay(10); } if (i) { PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr); @@ -213,7 +211,7 @@ static struct i2c_algorithm i2c_usb_algo = { /* * registering functions to load algorithms at runtime */ -int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) +static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) { PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]"); PDEBUG(DBG_ALGO, "ALGO debugging is enabled [i2c]"); @@ -248,15 +246,12 @@ int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap) /* usbvision specific I2C functions */ /* ----------------------------------------------------------------------- */ static struct i2c_adapter i2c_adap_template; -static struct i2c_algo_usb_data i2c_algo_template; static struct i2c_client i2c_client_template; int usbvision_init_i2c(struct usb_usbvision *usbvision) { memcpy(&usbvision->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); - memcpy(&usbvision->i2c_algo, &i2c_algo_template, - sizeof(struct i2c_algo_usb_data)); memcpy(&usbvision->i2c_client, &i2c_client_template, sizeof(struct i2c_client)); @@ -266,9 +261,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision) i2c_set_adapdata(&usbvision->i2c_adap, usbvision); i2c_set_clientdata(&usbvision->i2c_client, usbvision); - i2c_set_algo_usb_data(&usbvision->i2c_algo, usbvision); - usbvision->i2c_adap.algo_data = &usbvision->i2c_algo; usbvision->i2c_client.adapter = &usbvision->i2c_adap; if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { @@ -297,7 +290,6 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision) void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, void *arg) { - BUG_ON(NULL == usbvision->i2c_adap.algo_data); i2c_clients_command(&usbvision->i2c_adap, cmd, arg); } @@ -327,6 +319,9 @@ static int attach_inform(struct i2c_client *client) case 0x4a: PDEBUG(DBG_I2C,"attach_inform: saa7113 detected."); break; + case 0x48: + PDEBUG(DBG_I2C,"attach_inform: saa7111 detected."); + break; case 0xa0: PDEBUG(DBG_I2C,"attach_inform: eeprom detected."); break; @@ -531,21 +526,10 @@ static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, return rdcount; } -static struct i2c_algo_usb_data i2c_algo_template = { - .data = NULL, - .inb = usbvision_i2c_read, - .outb = usbvision_i2c_write, - .udelay = 10, - .mdelay = 10, - .timeout = 100, -}; - static struct i2c_adapter i2c_adap_template = { .owner = THIS_MODULE, .name = "usbvision", .id = I2C_HW_B_BT848, /* FIXME */ - .algo = NULL, - .algo_data = NULL, .client_register = attach_inform, .client_unregister = detach_inform, #ifdef I2C_ADAP_CLASS_TV_ANALOG @@ -559,9 +543,6 @@ static struct i2c_client i2c_client_template = { .name = "usbvision internal", }; -EXPORT_SYMBOL(usbvision_i2c_usb_add_bus); -EXPORT_SYMBOL(usbvision_i2c_usb_del_bus); - /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 864446c012e..8c7eba2a728 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -204,7 +204,7 @@ MODULE_ALIAS(DRIVER_ALIAS); static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd) { - struct video_device *vdev = to_video_device(cd); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); return video_get_drvdata(vdev); } @@ -214,81 +214,85 @@ static ssize_t show_version(struct class_device *cd, char *buf) } static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL); -static ssize_t show_model(struct class_device *class_dev, char *buf) +static ssize_t show_model(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString); } static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL); -static ssize_t show_hue(struct class_device *class_dev, char *buf) +static ssize_t show_hue(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_HUE; ctrl.value = 0; - call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); + if(usbvision->user) + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value >> 8); } static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); -static ssize_t show_contrast(struct class_device *class_dev, char *buf) +static ssize_t show_contrast(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_CONTRAST; ctrl.value = 0; - call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); + if(usbvision->user) + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value >> 8); } static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); -static ssize_t show_brightness(struct class_device *class_dev, char *buf) +static ssize_t show_brightness(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_BRIGHTNESS; ctrl.value = 0; - call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); + if(usbvision->user) + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value >> 8); } static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); -static ssize_t show_saturation(struct class_device *class_dev, char *buf) +static ssize_t show_saturation(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_SATURATION; ctrl.value = 0; - call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); + if(usbvision->user) + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value >> 8); } static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); -static ssize_t show_streaming(struct class_device *class_dev, char *buf) +static ssize_t show_streaming(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->streaming==Stream_On?1:0)); } static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL); -static ssize_t show_compression(struct class_device *class_dev, char *buf) +static ssize_t show_compression(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); } static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL); -static ssize_t show_device_bridge(struct class_device *class_dev, char *buf) +static ssize_t show_device_bridge(struct class_device *cd, char *buf) { - struct video_device *vdev = to_video_device(class_dev); + struct video_device *vdev = container_of(cd, struct video_device, class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->bridgeType); } @@ -297,31 +301,71 @@ static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL); static void usbvision_create_sysfs(struct video_device *vdev) { int res; - if (vdev) { - res=video_device_create_file(vdev, &class_device_attr_version); - res=video_device_create_file(vdev, &class_device_attr_model); - res=video_device_create_file(vdev, &class_device_attr_hue); - res=video_device_create_file(vdev, &class_device_attr_contrast); - res=video_device_create_file(vdev, &class_device_attr_brightness); - res=video_device_create_file(vdev, &class_device_attr_saturation); - res=video_device_create_file(vdev, &class_device_attr_streaming); - res=video_device_create_file(vdev, &class_device_attr_compression); - res=video_device_create_file(vdev, &class_device_attr_bridge); - } + if (!vdev) + return; + do { + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_version); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_model); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_hue); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_contrast); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_brightness); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_saturation); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_streaming); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_compression); + if (res<0) + break; + res=class_device_create_file(&vdev->class_dev, + &class_device_attr_bridge); + if (res>=0) + return; + } while (0); + + err("%s error: %d\n", __FUNCTION__, res); } static void usbvision_remove_sysfs(struct video_device *vdev) { if (vdev) { - video_device_remove_file(vdev, &class_device_attr_version); - video_device_remove_file(vdev, &class_device_attr_model); - video_device_remove_file(vdev, &class_device_attr_hue); - video_device_remove_file(vdev, &class_device_attr_contrast); - video_device_remove_file(vdev, &class_device_attr_brightness); - video_device_remove_file(vdev, &class_device_attr_saturation); - video_device_remove_file(vdev, &class_device_attr_streaming); - video_device_remove_file(vdev, &class_device_attr_compression); - video_device_remove_file(vdev, &class_device_attr_bridge); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_version); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_model); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_hue); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_contrast); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_brightness); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_saturation); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_streaming); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_compression); + class_device_remove_file(&vdev->class_dev, + &class_device_attr_bridge); } } @@ -353,20 +397,15 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) if(!errCode) { /* Allocate memory for the scratch ring buffer */ errCode = usbvision_scratch_alloc(usbvision); - if(!errCode) { - /* Allocate memory for the USB S buffers */ - errCode = usbvision_sbuf_alloc(usbvision); - if ((!errCode) && (usbvision->isocMode==ISOC_MODE_COMPRESS)) { - /* Allocate intermediate decompression buffers only if needed */ - errCode = usbvision_decompress_alloc(usbvision); - } + if ((!errCode) && (isocMode==ISOC_MODE_COMPRESS)) { + /* Allocate intermediate decompression buffers only if needed */ + errCode = usbvision_decompress_alloc(usbvision); } } if (errCode) { /* Deallocate all buffers if trouble */ usbvision_frames_free(usbvision); usbvision_scratch_free(usbvision); - usbvision_sbuf_free(usbvision); usbvision_decompress_free(usbvision); } } @@ -437,9 +476,8 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) usbvision_stop_isoc(usbvision); usbvision_decompress_free(usbvision); - usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size); + usbvision_frames_free(usbvision); usbvision_scratch_free(usbvision); - usbvision_sbuf_free(usbvision); usbvision->user--; @@ -1884,7 +1922,7 @@ static struct usb_driver usbvision_driver = { * This procedure preprocesses CustomDevice parameter if any * */ -void customdevice_process(void) +static void customdevice_process(void) { usbvision_device_data[0]=usbvision_device_data[1]; usbvision_table[0]=usbvision_table[1]; @@ -1939,22 +1977,22 @@ void customdevice_process(void) { case 'P': PDEBUG(DBG_PROBE, "VideoNorm=PAL"); - usbvision_device_data[0].VideoNorm=VIDEO_MODE_PAL; + usbvision_device_data[0].VideoNorm=V4L2_STD_PAL; break; case 'S': PDEBUG(DBG_PROBE, "VideoNorm=SECAM"); - usbvision_device_data[0].VideoNorm=VIDEO_MODE_SECAM; + usbvision_device_data[0].VideoNorm=V4L2_STD_SECAM; break; case 'N': PDEBUG(DBG_PROBE, "VideoNorm=NTSC"); - usbvision_device_data[0].VideoNorm=VIDEO_MODE_NTSC; + usbvision_device_data[0].VideoNorm=V4L2_STD_NTSC; break; default: PDEBUG(DBG_PROBE, "VideoNorm=PAL (by default)"); - usbvision_device_data[0].VideoNorm=VIDEO_MODE_PAL; + usbvision_device_data[0].VideoNorm=V4L2_STD_PAL; break; } goto2next(parse); diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index 0e7e3d653ca..e2bcaba9387 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h @@ -219,18 +219,6 @@ enum { ((udevice)->last_error == 0) && \ (!(udevice)->remove_pending)) -/* I2C structures */ -struct i2c_algo_usb_data { - void *data; /* private data for lowlevel routines */ - int (*inb) (void *data, unsigned char addr, char *buf, short len); - int (*outb) (void *data, unsigned char addr, char *buf, short len); - - /* local settings */ - int udelay; - int mdelay; - int timeout; -}; - #define I2C_USB_ADAP_MAX 16 /* ----------------------------------------------------------------- */ @@ -383,7 +371,6 @@ struct usb_usbvision { /* i2c Declaration Section*/ struct i2c_adapter i2c_adap; - struct i2c_algo_usb_data i2c_algo; struct i2c_client i2c_client; struct urb *ctrlUrb; @@ -489,19 +476,8 @@ struct usb_usbvision { /* i2c-algo-usb declaration */ /* --------------------------------------------------------------- */ -int usbvision_i2c_usb_add_bus(struct i2c_adapter *); int usbvision_i2c_usb_del_bus(struct i2c_adapter *); -static inline void *i2c_get_algo_usb_data (struct i2c_algo_usb_data *dev) -{ - return dev->data; -} - -static inline void i2c_set_algo_usb_data (struct i2c_algo_usb_data *dev, void *data) -{ - dev->data = data; -} - /* ----------------------------------------------------------------------- */ /* usbvision specific I2C functions */ @@ -510,7 +486,6 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision); void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg); /* defined in usbvision-core.c */ -void *usbvision_rvmalloc(unsigned long size); void usbvision_rvfree(void *mem, unsigned long size); int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg); int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, @@ -520,8 +495,6 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision); void usbvision_frames_free(struct usb_usbvision *usbvision); int usbvision_scratch_alloc(struct usb_usbvision *usbvision); void usbvision_scratch_free(struct usb_usbvision *usbvision); -int usbvision_sbuf_alloc(struct usb_usbvision *usbvision); -void usbvision_sbuf_free(struct usb_usbvision *usbvision); int usbvision_decompress_alloc(struct usb_usbvision *usbvision); void usbvision_decompress_free(struct usb_usbvision *usbvision); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 474ddb77964..bacb311b4f2 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -535,9 +535,9 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q) dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi"); - if (dma_q->kthread == NULL) { + if (IS_ERR(dma_q->kthread)) { printk(KERN_ERR "vivi: kernel_thread() failed\n"); - return -EINVAL; + return PTR_ERR(dma_q->kthread); } dprintk(1,"returning from %s\n",__FUNCTION__); return 0; @@ -1363,7 +1363,9 @@ static void __exit vivi_exit(void) struct vivi_dev *h; struct list_head *list; - list_for_each(list,&vivi_devlist) { + while (!list_empty(&vivi_devlist)) { + list = vivi_devlist.next; + list_del(list); h = list_entry(list, struct vivi_dev, vivi_devlist); kfree (h); } diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 4bdc886abc4..8d14f308f17 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -789,7 +789,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, case VIDIOCSPICT: { struct video_picture *vpic = arg; - if (vpic->depth != 16 || vpic->palette != VIDEO_PALETTE_YUV422) + if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV)) return -EINVAL; cam->brightness = vpic->brightness >> 8; diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index ddce2fb8342..9f403af7b04 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -1827,8 +1827,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) int err = 0; /* Work around to avoid FP arithmetics */ - #define __SC(x) ((x) << 10) - #define __UNSC(x) ((x) >> 10) + #define SC(x) ((x) << 10) + #define UNSC(x) ((x) >> 10) /* Make sure we are using a supported resolution */ if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, @@ -1836,15 +1836,15 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) goto error; /* Scaling factors */ - fw = __SC(win.width) / cam->maxwidth; - fh = __SC(win.height) / cam->maxheight; + fw = SC(win.width) / cam->maxwidth; + fh = SC(win.height) / cam->maxheight; /* Set up the width and height values used by the chip */ if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) { cam->vpp_flag |= VPP_UPSCALE; /* Calculate largest w,h mantaining the same w/h ratio */ - w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh; - h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight; + w = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh; + h = (fw >= fh) ? SC(win.height)/fw : cam->maxheight; if (w < cam->minwidth) /* just in case */ w = cam->minwidth; if (h < cam->minheight) /* just in case */ @@ -1861,8 +1861,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) /* Calculate cropped area manteining the right w/h ratio */ if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) { - cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh; - ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight; + cw = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh; + ch = (fw >= fh) ? SC(win.height)/fw : cam->maxheight; } else { cw = w; ch = h; @@ -1901,8 +1901,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) /* We have to scale win.x and win.y offsets */ if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) || (cam->vpp_flag & VPP_UPSCALE) ) { - ax = __SC(win.x)/fw; - ay = __SC(win.y)/fh; + ax = SC(win.x)/fw; + ay = SC(win.y)/fh; } else { ax = win.x; ay = win.y; @@ -1917,8 +1917,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) /* Adjust win.x, win.y */ if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) || (cam->vpp_flag & VPP_UPSCALE) ) { - win.x = __UNSC(ax*fw); - win.y = __UNSC(ay*fh); + win.x = UNSC(ax*fw); + win.y = UNSC(ay*fh); } else { win.x = ax; win.y = ay; diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index 168e431d7c7..b0752767ee4 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -429,7 +429,7 @@ zr36057_set_vfe (struct zoran *zr, reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); reg |= (DispMode << ZR36057_VFESPFR_DispMode); - if (format->palette != VIDEO_PALETTE_YUV422) + if (format->palette != VIDEO_PALETTE_YUV422 && format->palette != VIDEO_PALETTE_YUYV) reg |= ZR36057_VFESPFR_LittleEndian; /* RJ: I don't know, why the following has to be the opposite * of the corresponding ZR36060 setting, but only this way @@ -441,6 +441,7 @@ zr36057_set_vfe (struct zoran *zr, reg |= ZR36057_VFESPFR_TopField; switch (format->palette) { + case VIDEO_PALETTE_YUYV: case VIDEO_PALETTE_YUV422: reg |= ZR36057_VFESPFR_YUV422; break; diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 458dd9f830c..e2cb19b582a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -617,13 +617,15 @@ rx_next: * this round of polling */ if (rx_work) { + unsigned long flags; + if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; - local_irq_disable(); + local_irq_save(flags); cpw16_f(IntrMask, cp_intr_mask); __netif_rx_complete(dev); - local_irq_enable(); + local_irq_restore(flags); return 0; /* done */ } diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 8ebd68e2af9..dd698b033a6 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -780,12 +780,10 @@ static struct ethtool_ops ep93xx_ethtool_ops = { struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) { struct net_device *dev; - struct ep93xx_priv *ep; dev = alloc_etherdev(sizeof(struct ep93xx_priv)); if (dev == NULL) return NULL; - ep = netdev_priv(dev); memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN); @@ -840,9 +838,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev) struct ep93xx_priv *ep; int err; - data = pdev->dev.platform_data; if (pdev == NULL) return -ENODEV; + data = pdev->dev.platform_data; dev = ep93xx_dev_alloc(data); if (dev == NULL) { diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 474a4e3438d..5eb2ec68393 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -879,12 +879,14 @@ static int b44_poll(struct net_device *netdev, int *budget) } if (bp->istat & ISTAT_ERRORS) { - spin_lock_irq(&bp->lock); + unsigned long flags; + + spin_lock_irqsave(&bp->lock, flags); b44_halt(bp); b44_init_rings(bp); b44_init_hw(bp, 1); netif_wake_queue(bp->dev); - spin_unlock_irq(&bp->lock); + spin_unlock_irqrestore(&bp->lock, flags); done = 1; } diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index da459f7177c..fb96c87f9e5 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -100,6 +100,9 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, { "rx_header_split", E1000_STAT(rx_hdr_split) }, { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, + { "tx_smbus", E1000_STAT(stats.mgptc) }, + { "rx_smbus", E1000_STAT(stats.mgprc) }, + { "dropped_smbus", E1000_STAT(stats.mgpdc) }, }; #define E1000_QUEUE_STATS_LEN 0 diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 3655d902b0b..9be44699300 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -308,141 +308,160 @@ e1000_phy_init_script(struct e1000_hw *hw) int32_t e1000_set_mac_type(struct e1000_hw *hw) { - DEBUGFUNC("e1000_set_mac_type"); - - switch (hw->device_id) { - case E1000_DEV_ID_82542: - switch (hw->revision_id) { - case E1000_82542_2_0_REV_ID: - hw->mac_type = e1000_82542_rev2_0; - break; - case E1000_82542_2_1_REV_ID: - hw->mac_type = e1000_82542_rev2_1; - break; - default: - /* Invalid 82542 revision ID */ - return -E1000_ERR_MAC_TYPE; - } - break; - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - hw->mac_type = e1000_82543; - break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - hw->mac_type = e1000_82544; - break; - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - hw->mac_type = e1000_82540; - break; - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - hw->mac_type = e1000_82545; - break; - case E1000_DEV_ID_82545GM_COPPER: - case E1000_DEV_ID_82545GM_FIBER: - case E1000_DEV_ID_82545GM_SERDES: - hw->mac_type = e1000_82545_rev_3; - break; - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546EB_QUAD_COPPER: - hw->mac_type = e1000_82546; - break; - case E1000_DEV_ID_82546GB_COPPER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82546GB_SERDES: - case E1000_DEV_ID_82546GB_PCIE: - case E1000_DEV_ID_82546GB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - hw->mac_type = e1000_82546_rev_3; - break; - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EI_MOBILE: - case E1000_DEV_ID_82541ER_LOM: - hw->mac_type = e1000_82541; - break; - case E1000_DEV_ID_82541ER: - case E1000_DEV_ID_82541GI: - case E1000_DEV_ID_82541GI_LF: - case E1000_DEV_ID_82541GI_MOBILE: - hw->mac_type = e1000_82541_rev_2; - break; - case E1000_DEV_ID_82547EI: - case E1000_DEV_ID_82547EI_MOBILE: - hw->mac_type = e1000_82547; - break; - case E1000_DEV_ID_82547GI: - hw->mac_type = e1000_82547_rev_2; - break; - case E1000_DEV_ID_82571EB_COPPER: - case E1000_DEV_ID_82571EB_FIBER: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: - hw->mac_type = e1000_82571; - break; - case E1000_DEV_ID_82572EI_COPPER: - case E1000_DEV_ID_82572EI_FIBER: - case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_82572EI: - hw->mac_type = e1000_82572; - break; - case E1000_DEV_ID_82573E: - case E1000_DEV_ID_82573E_IAMT: - case E1000_DEV_ID_82573L: - hw->mac_type = e1000_82573; - break; - case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: - case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->mac_type = e1000_80003es2lan; - break; - case E1000_DEV_ID_ICH8_IGP_M_AMT: - case E1000_DEV_ID_ICH8_IGP_AMT: - case E1000_DEV_ID_ICH8_IGP_C: - case E1000_DEV_ID_ICH8_IFE: - case E1000_DEV_ID_ICH8_IFE_GT: - case E1000_DEV_ID_ICH8_IFE_G: - case E1000_DEV_ID_ICH8_IGP_M: - hw->mac_type = e1000_ich8lan; - break; - default: - /* Should never have loaded on this device */ - return -E1000_ERR_MAC_TYPE; - } - - switch (hw->mac_type) { - case e1000_ich8lan: - hw->swfwhw_semaphore_present = TRUE; - hw->asf_firmware_present = TRUE; - break; - case e1000_80003es2lan: - hw->swfw_sync_present = TRUE; - /* fall through */ - case e1000_82571: - case e1000_82572: - case e1000_82573: - hw->eeprom_semaphore_present = TRUE; - /* fall through */ - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->asf_firmware_present = TRUE; - break; - default: - break; - } - - return E1000_SUCCESS; + DEBUGFUNC("e1000_set_mac_type"); + + switch (hw->device_id) { + case E1000_DEV_ID_82542: + switch (hw->revision_id) { + case E1000_82542_2_0_REV_ID: + hw->mac_type = e1000_82542_rev2_0; + break; + case E1000_82542_2_1_REV_ID: + hw->mac_type = e1000_82542_rev2_1; + break; + default: + /* Invalid 82542 revision ID */ + return -E1000_ERR_MAC_TYPE; + } + break; + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + hw->mac_type = e1000_82543; + break; + case E1000_DEV_ID_82544EI_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82544GC_COPPER: + case E1000_DEV_ID_82544GC_LOM: + hw->mac_type = e1000_82544; + break; + case E1000_DEV_ID_82540EM: + case E1000_DEV_ID_82540EM_LOM: + case E1000_DEV_ID_82540EP: + case E1000_DEV_ID_82540EP_LOM: + case E1000_DEV_ID_82540EP_LP: + hw->mac_type = e1000_82540; + break; + case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + hw->mac_type = e1000_82545; + break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + hw->mac_type = e1000_82545_rev_3; + break; + case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: + hw->mac_type = e1000_82546; + break; + case E1000_DEV_ID_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + hw->mac_type = e1000_82546_rev_3; + break; + case E1000_DEV_ID_82541EI: + case E1000_DEV_ID_82541EI_MOBILE: + case E1000_DEV_ID_82541ER_LOM: + hw->mac_type = e1000_82541; + break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_LF: + case E1000_DEV_ID_82541GI_MOBILE: + hw->mac_type = e1000_82541_rev_2; + break; + case E1000_DEV_ID_82547EI: + case E1000_DEV_ID_82547EI_MOBILE: + hw->mac_type = e1000_82547; + break; + case E1000_DEV_ID_82547GI: + hw->mac_type = e1000_82547_rev_2; + break; + case E1000_DEV_ID_82571EB_COPPER: + case E1000_DEV_ID_82571EB_FIBER: + case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: + hw->mac_type = e1000_82571; + break; + case E1000_DEV_ID_82572EI_COPPER: + case E1000_DEV_ID_82572EI_FIBER: + case E1000_DEV_ID_82572EI_SERDES: + case E1000_DEV_ID_82572EI: + hw->mac_type = e1000_82572; + break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + case E1000_DEV_ID_82573L: + hw->mac_type = e1000_82573; + break; + case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: + case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: + hw->mac_type = e1000_80003es2lan; + break; + case E1000_DEV_ID_ICH8_IGP_M_AMT: + case E1000_DEV_ID_ICH8_IGP_AMT: + case E1000_DEV_ID_ICH8_IGP_C: + case E1000_DEV_ID_ICH8_IFE: + case E1000_DEV_ID_ICH8_IFE_GT: + case E1000_DEV_ID_ICH8_IFE_G: + case E1000_DEV_ID_ICH8_IGP_M: + hw->mac_type = e1000_ich8lan; + break; + default: + /* Should never have loaded on this device */ + return -E1000_ERR_MAC_TYPE; + } + + switch (hw->mac_type) { + case e1000_ich8lan: + hw->swfwhw_semaphore_present = TRUE; + hw->asf_firmware_present = TRUE; + break; + case e1000_80003es2lan: + hw->swfw_sync_present = TRUE; + /* fall through */ + case e1000_82571: + case e1000_82572: + case e1000_82573: + hw->eeprom_semaphore_present = TRUE; + /* fall through */ + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->asf_firmware_present = TRUE; + break; + default: + break; + } + + /* The 82543 chip does not count tx_carrier_errors properly in + * FD mode + */ + if (hw->mac_type == e1000_82543) + hw->bad_tx_carr_stats_fd = TRUE; + + /* capable of receiving management packets to the host */ + if (hw->mac_type >= e1000_82571) + hw->has_manc2h = TRUE; + + /* In rare occasions, ESB2 systems would end up started without + * the RX unit being turned on. + */ + if (hw->mac_type == e1000_80003es2lan) + hw->rx_needs_kicking = TRUE; + + if (hw->mac_type > e1000_82544) + hw->has_smbus = TRUE; + + return E1000_SUCCESS; } /***************************************************************************** @@ -6575,7 +6594,7 @@ e1000_get_bus_info(struct e1000_hw *hw) switch (hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: - hw->bus_type = e1000_bus_type_unknown; + hw->bus_type = e1000_bus_type_pci; hw->bus_speed = e1000_bus_speed_unknown; hw->bus_width = e1000_bus_width_unknown; break; @@ -7817,9 +7836,8 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw) fwsm = E1000_READ_REG(hw, FWSM); factps = E1000_READ_REG(hw, FACTPS); - if (((fwsm & E1000_FWSM_MODE_MASK) == - (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) && - (factps & E1000_FACTPS_MNGCG)) + if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) == + e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG)) return TRUE; } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 3321fb13bfa..d6710588334 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1301,165 +1301,170 @@ struct e1000_ffvt_entry { #define E1000_82542_RSSIR E1000_RSSIR #define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA #define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC +#define E1000_82542_MANC2H E1000_MANC2H /* Statistics counters collected by the MAC */ struct e1000_hw_stats { - uint64_t crcerrs; - uint64_t algnerrc; - uint64_t symerrs; - uint64_t rxerrc; - uint64_t txerrc; - uint64_t mpc; - uint64_t scc; - uint64_t ecol; - uint64_t mcc; - uint64_t latecol; - uint64_t colc; - uint64_t dc; - uint64_t tncrs; - uint64_t sec; - uint64_t cexterr; - uint64_t rlec; - uint64_t xonrxc; - uint64_t xontxc; - uint64_t xoffrxc; - uint64_t xofftxc; - uint64_t fcruc; - uint64_t prc64; - uint64_t prc127; - uint64_t prc255; - uint64_t prc511; - uint64_t prc1023; - uint64_t prc1522; - uint64_t gprc; - uint64_t bprc; - uint64_t mprc; - uint64_t gptc; - uint64_t gorcl; - uint64_t gorch; - uint64_t gotcl; - uint64_t gotch; - uint64_t rnbc; - uint64_t ruc; - uint64_t rfc; - uint64_t roc; - uint64_t rlerrc; - uint64_t rjc; - uint64_t mgprc; - uint64_t mgpdc; - uint64_t mgptc; - uint64_t torl; - uint64_t torh; - uint64_t totl; - uint64_t toth; - uint64_t tpr; - uint64_t tpt; - uint64_t ptc64; - uint64_t ptc127; - uint64_t ptc255; - uint64_t ptc511; - uint64_t ptc1023; - uint64_t ptc1522; - uint64_t mptc; - uint64_t bptc; - uint64_t tsctc; - uint64_t tsctfc; - uint64_t iac; - uint64_t icrxptc; - uint64_t icrxatc; - uint64_t ictxptc; - uint64_t ictxatc; - uint64_t ictxqec; - uint64_t ictxqmtc; - uint64_t icrxdmtc; - uint64_t icrxoc; + uint64_t crcerrs; + uint64_t algnerrc; + uint64_t symerrs; + uint64_t rxerrc; + uint64_t txerrc; + uint64_t mpc; + uint64_t scc; + uint64_t ecol; + uint64_t mcc; + uint64_t latecol; + uint64_t colc; + uint64_t dc; + uint64_t tncrs; + uint64_t sec; + uint64_t cexterr; + uint64_t rlec; + uint64_t xonrxc; + uint64_t xontxc; + uint64_t xoffrxc; + uint64_t xofftxc; + uint64_t fcruc; + uint64_t prc64; + uint64_t prc127; + uint64_t prc255; + uint64_t prc511; + uint64_t prc1023; + uint64_t prc1522; + uint64_t gprc; + uint64_t bprc; + uint64_t mprc; + uint64_t gptc; + uint64_t gorcl; + uint64_t gorch; + uint64_t gotcl; + uint64_t gotch; + uint64_t rnbc; + uint64_t ruc; + uint64_t rfc; + uint64_t roc; + uint64_t rlerrc; + uint64_t rjc; + uint64_t mgprc; + uint64_t mgpdc; + uint64_t mgptc; + uint64_t torl; + uint64_t torh; + uint64_t totl; + uint64_t toth; + uint64_t tpr; + uint64_t tpt; + uint64_t ptc64; + uint64_t ptc127; + uint64_t ptc255; + uint64_t ptc511; + uint64_t ptc1023; + uint64_t ptc1522; + uint64_t mptc; + uint64_t bptc; + uint64_t tsctc; + uint64_t tsctfc; + uint64_t iac; + uint64_t icrxptc; + uint64_t icrxatc; + uint64_t ictxptc; + uint64_t ictxatc; + uint64_t ictxqec; + uint64_t ictxqmtc; + uint64_t icrxdmtc; + uint64_t icrxoc; }; /* Structure containing variables used by the shared code (e1000_hw.c) */ struct e1000_hw { - uint8_t __iomem *hw_addr; - uint8_t __iomem *flash_address; - e1000_mac_type mac_type; - e1000_phy_type phy_type; - uint32_t phy_init_script; - e1000_media_type media_type; - void *back; - struct e1000_shadow_ram *eeprom_shadow_ram; - uint32_t flash_bank_size; - uint32_t flash_base_addr; - e1000_fc_type fc; - e1000_bus_speed bus_speed; - e1000_bus_width bus_width; - e1000_bus_type bus_type; - struct e1000_eeprom_info eeprom; - e1000_ms_type master_slave; - e1000_ms_type original_master_slave; - e1000_ffe_config ffe_config_state; - uint32_t asf_firmware_present; - uint32_t eeprom_semaphore_present; - uint32_t swfw_sync_present; - uint32_t swfwhw_semaphore_present; - unsigned long io_base; - uint32_t phy_id; - uint32_t phy_revision; - uint32_t phy_addr; - uint32_t original_fc; - uint32_t txcw; - uint32_t autoneg_failed; - uint32_t max_frame_size; - uint32_t min_frame_size; - uint32_t mc_filter_type; - uint32_t num_mc_addrs; - uint32_t collision_delta; - uint32_t tx_packet_delta; - uint32_t ledctl_default; - uint32_t ledctl_mode1; - uint32_t ledctl_mode2; - boolean_t tx_pkt_filtering; - struct e1000_host_mng_dhcp_cookie mng_cookie; - uint16_t phy_spd_default; - uint16_t autoneg_advertised; - uint16_t pci_cmd_word; - uint16_t fc_high_water; - uint16_t fc_low_water; - uint16_t fc_pause_time; - uint16_t current_ifs_val; - uint16_t ifs_min_val; - uint16_t ifs_max_val; - uint16_t ifs_step_size; - uint16_t ifs_ratio; - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_id; - uint16_t subsystem_vendor_id; - uint8_t revision_id; - uint8_t autoneg; - uint8_t mdix; - uint8_t forced_speed_duplex; - uint8_t wait_autoneg_complete; - uint8_t dma_fairness; - uint8_t mac_addr[NODE_ADDRESS_SIZE]; - uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; - boolean_t disable_polarity_correction; - boolean_t speed_downgraded; - e1000_smart_speed smart_speed; - e1000_dsp_config dsp_config_state; - boolean_t get_link_status; - boolean_t serdes_link_down; - boolean_t tbi_compatibility_en; - boolean_t tbi_compatibility_on; - boolean_t laa_is_present; - boolean_t phy_reset_disable; - boolean_t initialize_hw_bits_disable; - boolean_t fc_send_xon; - boolean_t fc_strict_ieee; - boolean_t report_tx_early; - boolean_t adaptive_ifs; - boolean_t ifs_params_forced; - boolean_t in_ifs_mode; - boolean_t mng_reg_access_disabled; - boolean_t leave_av_bit_off; - boolean_t kmrn_lock_loss_workaround_disabled; + uint8_t __iomem *hw_addr; + uint8_t __iomem *flash_address; + e1000_mac_type mac_type; + e1000_phy_type phy_type; + uint32_t phy_init_script; + e1000_media_type media_type; + void *back; + struct e1000_shadow_ram *eeprom_shadow_ram; + uint32_t flash_bank_size; + uint32_t flash_base_addr; + e1000_fc_type fc; + e1000_bus_speed bus_speed; + e1000_bus_width bus_width; + e1000_bus_type bus_type; + struct e1000_eeprom_info eeprom; + e1000_ms_type master_slave; + e1000_ms_type original_master_slave; + e1000_ffe_config ffe_config_state; + uint32_t asf_firmware_present; + uint32_t eeprom_semaphore_present; + uint32_t swfw_sync_present; + uint32_t swfwhw_semaphore_present; + unsigned long io_base; + uint32_t phy_id; + uint32_t phy_revision; + uint32_t phy_addr; + uint32_t original_fc; + uint32_t txcw; + uint32_t autoneg_failed; + uint32_t max_frame_size; + uint32_t min_frame_size; + uint32_t mc_filter_type; + uint32_t num_mc_addrs; + uint32_t collision_delta; + uint32_t tx_packet_delta; + uint32_t ledctl_default; + uint32_t ledctl_mode1; + uint32_t ledctl_mode2; + boolean_t tx_pkt_filtering; + struct e1000_host_mng_dhcp_cookie mng_cookie; + uint16_t phy_spd_default; + uint16_t autoneg_advertised; + uint16_t pci_cmd_word; + uint16_t fc_high_water; + uint16_t fc_low_water; + uint16_t fc_pause_time; + uint16_t current_ifs_val; + uint16_t ifs_min_val; + uint16_t ifs_max_val; + uint16_t ifs_step_size; + uint16_t ifs_ratio; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_id; + uint16_t subsystem_vendor_id; + uint8_t revision_id; + uint8_t autoneg; + uint8_t mdix; + uint8_t forced_speed_duplex; + uint8_t wait_autoneg_complete; + uint8_t dma_fairness; + uint8_t mac_addr[NODE_ADDRESS_SIZE]; + uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; + boolean_t disable_polarity_correction; + boolean_t speed_downgraded; + e1000_smart_speed smart_speed; + e1000_dsp_config dsp_config_state; + boolean_t get_link_status; + boolean_t serdes_link_down; + boolean_t tbi_compatibility_en; + boolean_t tbi_compatibility_on; + boolean_t laa_is_present; + boolean_t phy_reset_disable; + boolean_t initialize_hw_bits_disable; + boolean_t fc_send_xon; + boolean_t fc_strict_ieee; + boolean_t report_tx_early; + boolean_t adaptive_ifs; + boolean_t ifs_params_forced; + boolean_t in_ifs_mode; + boolean_t mng_reg_access_disabled; + boolean_t leave_av_bit_off; + boolean_t kmrn_lock_loss_workaround_disabled; + boolean_t bad_tx_carr_stats_fd; + boolean_t has_manc2h; + boolean_t rx_needs_kicking; + boolean_t has_smbus; }; @@ -2418,6 +2423,7 @@ struct e1000_host_command_info { #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ +#define E1000_PBA_20K 0x0014 #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 #define E1000_PBA_30K 0x001E diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 73f3a85fd23..4c1ff752048 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -213,6 +213,12 @@ static void e1000_netpoll (struct net_device *netdev); extern void e1000_check_options(struct e1000_adapter *adapter); +#define COPYBREAK_DEFAULT 256 +static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT; +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state); static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); @@ -264,7 +270,13 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_register_driver(&e1000_driver); - + if (copybreak != COPYBREAK_DEFAULT) { + if (copybreak == 0) + printk(KERN_INFO "e1000: copybreak disabled\n"); + else + printk(KERN_INFO "e1000: copybreak enabled for " + "packets <= %u bytes\n", copybreak); + } return ret; } @@ -464,6 +476,52 @@ e1000_get_hw_control(struct e1000_adapter *adapter) } } +static void +e1000_init_manageability(struct e1000_adapter *adapter) +{ + if (adapter->en_mng_pt) { + uint32_t manc = E1000_READ_REG(&adapter->hw, MANC); + + /* disable hardware interception of ARP */ + manc &= ~(E1000_MANC_ARP_EN); + + /* enable receiving management packets to the host */ + /* this will probably generate destination unreachable messages + * from the host OS, but the packets will be handled on SMBUS */ + if (adapter->hw.has_manc2h) { + uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H); + + manc |= E1000_MANC_EN_MNG2HOST; +#define E1000_MNG2HOST_PORT_623 (1 << 5) +#define E1000_MNG2HOST_PORT_664 (1 << 6) + manc2h |= E1000_MNG2HOST_PORT_623; + manc2h |= E1000_MNG2HOST_PORT_664; + E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h); + } + + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } +} + +static void +e1000_release_manageability(struct e1000_adapter *adapter) +{ + if (adapter->en_mng_pt) { + uint32_t manc = E1000_READ_REG(&adapter->hw, MANC); + + /* re-enable hardware interception of ARP */ + manc |= E1000_MANC_ARP_EN; + + if (adapter->hw.has_manc2h) + manc &= ~E1000_MANC_EN_MNG2HOST; + + /* don't explicitly have to mess with MANC2H since + * MANC has an enable disable that gates MANC2H */ + + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } +} + int e1000_up(struct e1000_adapter *adapter) { @@ -475,6 +533,7 @@ e1000_up(struct e1000_adapter *adapter) e1000_set_multi(netdev); e1000_restore_vlan(adapter); + e1000_init_manageability(adapter); e1000_configure_tx(adapter); e1000_setup_rctl(adapter); @@ -497,7 +556,8 @@ e1000_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->flags); - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); + /* fire a link change interrupt to start the watchdog */ + E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC); return 0; } @@ -614,16 +674,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { - uint32_t pba, manc; + uint32_t pba = 0, tx_space, min_tx_space, min_rx_space; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; + boolean_t legacy_pba_adjust = FALSE; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. */ switch (adapter->hw.mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + case e1000_82544: + case e1000_82540: + case e1000_82541: + case e1000_82541_rev_2: + legacy_pba_adjust = TRUE; + pba = E1000_PBA_48K; + break; + case e1000_82545: + case e1000_82545_rev_3: + case e1000_82546: + case e1000_82546_rev_3: + pba = E1000_PBA_48K; + break; case e1000_82547: case e1000_82547_rev_2: + legacy_pba_adjust = TRUE; pba = E1000_PBA_30K; break; case e1000_82571: @@ -632,27 +710,80 @@ e1000_reset(struct e1000_adapter *adapter) pba = E1000_PBA_38K; break; case e1000_82573: - pba = E1000_PBA_12K; + pba = E1000_PBA_20K; break; case e1000_ich8lan: pba = E1000_PBA_8K; - break; - default: - pba = E1000_PBA_48K; + case e1000_undefined: + case e1000_num_macs: break; } - if ((adapter->hw.mac_type != e1000_82573) && - (adapter->netdev->mtu > E1000_RXBUFFER_8192)) - pba -= 8; /* allocate more FIFO for Tx */ + if (legacy_pba_adjust == TRUE) { + if (adapter->netdev->mtu > E1000_RXBUFFER_8192) + pba -= 8; /* allocate more FIFO for Tx */ + if (adapter->hw.mac_type == e1000_82547) { + adapter->tx_fifo_head = 0; + adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; + adapter->tx_fifo_size = + (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; + atomic_set(&adapter->tx_fifo_stall, 0); + } + } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) { + /* adjust PBA for jumbo frames */ + E1000_WRITE_REG(&adapter->hw, PBA, pba); + + /* To maintain wire speed transmits, the Tx FIFO should be + * large enough to accomodate two full transmit packets, + * rounded up to the next 1KB and expressed in KB. Likewise, + * the Rx FIFO should be large enough to accomodate at least + * one full receive packet and is similarly rounded up and + * expressed in KB. */ + pba = E1000_READ_REG(&adapter->hw, PBA); + /* upper 16 bits has Tx packet buffer allocation size in KB */ + tx_space = pba >> 16; + /* lower 16 bits has Rx packet buffer allocation size in KB */ + pba &= 0xffff; + /* don't include ethernet FCS because hardware appends/strips */ + min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE + + VLAN_TAG_SIZE; + min_tx_space = min_rx_space; + min_tx_space *= 2; + E1000_ROUNDUP(min_tx_space, 1024); + min_tx_space >>= 10; + E1000_ROUNDUP(min_rx_space, 1024); + min_rx_space >>= 10; + + /* If current Tx allocation is less than the min Tx FIFO size, + * and the min Tx FIFO size is less than the current Rx FIFO + * allocation, take space away from current Rx allocation */ + if (tx_space < min_tx_space && + ((min_tx_space - tx_space) < pba)) { + pba = pba - (min_tx_space - tx_space); + + /* PCI/PCIx hardware has PBA alignment constraints */ + switch (adapter->hw.mac_type) { + case e1000_82545 ... e1000_82546_rev_3: + pba &= ~(E1000_PBA_8K - 1); + break; + default: + break; + } - if (adapter->hw.mac_type == e1000_82547) { - adapter->tx_fifo_head = 0; - adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; - adapter->tx_fifo_size = - (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; - atomic_set(&adapter->tx_fifo_stall, 0); + /* if short on rx space, rx wins and must trump tx + * adjustment or use Early Receive if available */ + if (pba < min_rx_space) { + switch (adapter->hw.mac_type) { + case e1000_82573: + /* ERT enabled in e1000_configure_rx */ + break; + default: + pba = min_rx_space; + break; + } + } + } } E1000_WRITE_REG(&adapter->hw, PBA, pba); @@ -685,6 +816,20 @@ e1000_reset(struct e1000_adapter *adapter) if (e1000_init_hw(&adapter->hw)) DPRINTK(PROBE, ERR, "Hardware Error\n"); e1000_update_mng_vlan(adapter); + + /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */ + if (adapter->hw.mac_type >= e1000_82544 && + adapter->hw.mac_type <= e1000_82547_rev_2 && + adapter->hw.autoneg == 1 && + adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) { + uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL); + /* clear phy power management bit if we are in gig only mode, + * which if enabled will attempt negotiation to 100Mb, which + * can cause a loss of link at power off or driver unload */ + ctrl &= ~E1000_CTRL_SWDPIN3; + E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); + } + /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); @@ -705,14 +850,7 @@ e1000_reset(struct e1000_adapter *adapter) phy_data); } - if ((adapter->en_mng_pt) && - (adapter->hw.mac_type >= e1000_82540) && - (adapter->hw.mac_type < e1000_82571) && - (adapter->hw.media_type == e1000_media_type_copper)) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } + e1000_release_manageability(adapter); } /** @@ -857,6 +995,12 @@ e1000_probe(struct pci_dev *pdev, (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; +#ifdef CONFIG_DEBUG_SLAB + /* 82544's work arounds do not play nicely with DEBUG SLAB */ + if (adapter->hw.mac_type == e1000_82544) + netdev->features &= ~NETIF_F_TSO; +#endif + #ifdef NETIF_F_TSO6 if (adapter->hw.mac_type > e1000_82547_rev_2) netdev->features |= NETIF_F_TSO6; @@ -1078,22 +1222,13 @@ e1000_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc; #ifdef CONFIG_E1000_NAPI int i; #endif flush_scheduled_work(); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - if (manc & E1000_MANC_SMBUS_EN) { - manc |= E1000_MANC_ARP_EN; - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - } + e1000_release_manageability(adapter); /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ @@ -1531,9 +1666,9 @@ e1000_configure_tx(struct e1000_adapter *adapter) } /* Set the default values for the Tx Inter Packet Gap timer */ - - if (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes) + if (adapter->hw.mac_type <= e1000_82547_rev_2 && + (hw->media_type == e1000_media_type_fiber || + hw->media_type == e1000_media_type_internal_serdes)) tipg = DEFAULT_82543_TIPG_IPGT_FIBER; else tipg = DEFAULT_82543_TIPG_IPGT_COPPER; @@ -2528,6 +2663,13 @@ e1000_watchdog(unsigned long data) netif_wake_queue(netdev); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); adapter->smartspeed = 0; + } else { + /* make sure the receive unit is started */ + if (adapter->hw.rx_needs_kicking) { + struct e1000_hw *hw = &adapter->hw; + uint32_t rctl = E1000_READ_REG(hw, RCTL); + E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN); + } } } else { if (netif_carrier_ok(netdev)) { @@ -2628,29 +2770,34 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, if (packets == 0) goto update_itr_done; - switch (itr_setting) { case lowest_latency: - if ((packets < 5) && (bytes > 512)) + /* jumbo frames get bulk treatment*/ + if (bytes/packets > 8000) + retval = bulk_latency; + else if ((packets < 5) && (bytes > 512)) retval = low_latency; break; case low_latency: /* 50 usec aka 20000 ints/s */ if (bytes > 10000) { - if ((packets < 10) || - ((bytes/packets) > 1200)) + /* jumbo frames need bulk latency setting */ + if (bytes/packets > 8000) + retval = bulk_latency; + else if ((packets < 10) || ((bytes/packets) > 1200)) retval = bulk_latency; else if ((packets > 35)) retval = lowest_latency; - } else if (packets <= 2 && bytes < 512) + } else if (bytes/packets > 2000) + retval = bulk_latency; + else if (packets <= 2 && bytes < 512) retval = lowest_latency; break; case bulk_latency: /* 250 usec aka 4000 ints/s */ if (bytes > 25000) { if (packets > 35) retval = low_latency; - } else { - if (bytes < 6000) - retval = low_latency; + } else if (bytes < 6000) { + retval = low_latency; } break; } @@ -2679,17 +2826,20 @@ static void e1000_set_itr(struct e1000_adapter *adapter) adapter->tx_itr, adapter->total_tx_packets, adapter->total_tx_bytes); + /* conservative mode (itr 3) eliminates the lowest_latency setting */ + if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency) + adapter->tx_itr = low_latency; + adapter->rx_itr = e1000_update_itr(adapter, adapter->rx_itr, adapter->total_rx_packets, adapter->total_rx_bytes); + /* conservative mode (itr 3) eliminates the lowest_latency setting */ + if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency) + adapter->rx_itr = low_latency; current_itr = max(adapter->rx_itr, adapter->tx_itr); - /* conservative mode eliminates the lowest_latency setting */ - if (current_itr == lowest_latency && (adapter->itr_setting == 3)) - current_itr = low_latency; - switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: @@ -3168,6 +3318,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) { switch (adapter->hw.mac_type) { unsigned int pull_size; + case e1000_82544: + /* Make sure we have room to chop off 4 bytes, + * and that the end alignment will work out to + * this hardware's requirements + * NOTE: this is a TSO only workaround + * if end byte alignment not correct move us + * into the next dword */ + if ((unsigned long)(skb->tail - 1) & 4) + break; + /* fall through */ case e1000_82571: case e1000_82572: case e1000_82573: @@ -3419,12 +3579,11 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; netdev->mtu = new_mtu; + adapter->hw.max_frame_size = max_frame; if (netif_running(netdev)) e1000_reinit_locked(adapter); - adapter->hw.max_frame_size = max_frame; - return 0; } @@ -3573,6 +3732,11 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->net_stats.tx_aborted_errors = adapter->stats.ecol; adapter->net_stats.tx_window_errors = adapter->stats.latecol; adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs; + if (adapter->hw.bad_tx_carr_stats_fd && + adapter->link_duplex == FULL_DUPLEX) { + adapter->net_stats.tx_carrier_errors = 0; + adapter->stats.tncrs = 0; + } /* Tx Dropped needs to be maintained elsewhere */ @@ -3590,6 +3754,13 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->phy_stats.receive_errors += phy_tmp; } + /* Management Stats */ + if (adapter->hw.has_smbus) { + adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC); + adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC); + adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC); + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); } #ifdef CONFIG_PCI_MSI @@ -3868,11 +4039,11 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, cleaned = (i == eop); if (cleaned) { - /* this packet count is wrong for TSO but has a - * tendency to make dynamic ITR change more - * towards bulk */ + struct sk_buff *skb = buffer_info->skb; + unsigned int segs = skb_shinfo(skb)->gso_segs; + total_tx_packets += segs; total_tx_packets++; - total_tx_bytes += buffer_info->skb->len; + total_tx_bytes += skb->len; } e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->upper.data = 0; @@ -4094,8 +4265,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ -#define E1000_CB_LENGTH 256 - if (length < E1000_CB_LENGTH) { + if (length < copybreak) { struct sk_buff *new_skb = netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { @@ -4253,7 +4423,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* page alloc/put takes too long and effects small packet * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { + if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) { u8 *vaddr; /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping @@ -4998,7 +5168,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t ctrl, ctrl_ext, rctl, manc, status; + uint32_t ctrl, ctrl_ext, rctl, status; uint32_t wufc = adapter->wol; #ifdef CONFIG_PM int retval = 0; @@ -5067,16 +5237,12 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - if (manc & E1000_MANC_SMBUS_EN) { - manc |= E1000_MANC_ARP_EN; - E1000_WRITE_REG(&adapter->hw, MANC, manc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } + e1000_release_manageability(adapter); + + /* make sure adapter isn't asleep if manageability is enabled */ + if (adapter->en_mng_pt) { + pci_enable_wake(pdev, PCI_D3hot, 1); + pci_enable_wake(pdev, PCI_D3cold, 1); } if (adapter->hw.phy_type == e1000_phy_igp_3) @@ -5102,7 +5268,7 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc, err; + uint32_t err; pci_set_power_state(pdev, PCI_D0); e1000_pci_restore_state(adapter); @@ -5122,19 +5288,13 @@ e1000_resume(struct pci_dev *pdev) e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); + e1000_init_manageability(adapter); + if (netif_running(netdev)) e1000_up(adapter); netif_device_attach(netdev); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc &= ~(E1000_MANC_ARP_EN); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - /* If the controller is 82573 and f/w is AMT, do not set * DRV_LOAD until the interface is up. For all other cases, * let the f/w know that the h/w is now under the control @@ -5235,7 +5395,8 @@ static void e1000_io_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - uint32_t manc, swsm; + + e1000_init_manageability(adapter); if (netif_running(netdev)) { if (e1000_up(adapter)) { @@ -5246,26 +5407,14 @@ static void e1000_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc &= ~(E1000_MANC_ARP_EN); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - - switch (adapter->hw.mac_type) { - case e1000_82573: - swsm = E1000_READ_REG(&adapter->hw, SWSM); - E1000_WRITE_REG(&adapter->hw, SWSM, - swsm | E1000_SWSM_DRV_LOAD); - break; - default: - break; - } + /* If the controller is 82573 and f/w is AMT, do not set + * DRV_LOAD until the interface is up. For all other cases, + * let the f/w know that the h/w is now under the control + * of the driver. */ + if (adapter->hw.mac_type != e1000_82573 || + !e1000_check_mng_mode(&adapter->hw)) + e1000_get_hw_control(adapter); - if (netif_running(netdev)) - mod_timer(&adapter->watchdog_timer, jiffies); } /* e1000_main.c */ diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index cbfcd7f2889..cf2a279307e 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -487,7 +487,9 @@ e1000_check_options(struct e1000_adapter *adapter) e1000_validate_option(&adapter->itr, &opt, adapter); /* save the setting, because the dynamic bits change itr */ - adapter->itr_setting = adapter->itr; + /* clear the lower two bits because they are + * used as control */ + adapter->itr_setting = adapter->itr & ~3; break; } } else { diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 439f4133829..2f48fe9a29a 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3,8 +3,7 @@ * * Note: This driver is a cleanroom reimplementation based on reverse * engineered documentation written by Carl-Daniel Hailfinger - * and Andrew de Quincey. It's neither supported nor endorsed - * by NVIDIA Corp. Use at your own risk. + * and Andrew de Quincey. * * NVIDIA, nForce and other NVIDIA marks are trademarks or registered * trademarks of NVIDIA Corporation in the United States and other @@ -14,7 +13,7 @@ * Copyright (C) 2004 Andrew de Quincey (wol support) * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane * IRQ rate fixes, bigendian fixes, cleanups, verification) - * Copyright (c) 2004 NVIDIA Corporation + * Copyright (c) 2004,5,6 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2576,14 +2575,15 @@ static int nv_napi_poll(struct net_device *dev, int *budget) int pkts, limit = min(*budget, dev->quota); struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); + unsigned long flags; pkts = nv_rx_process(dev, limit); if (nv_alloc_rx(dev)) { - spin_lock_irq(&np->lock); + spin_lock_irqsave(&np->lock, flags); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irq(&np->lock); + spin_unlock_irqrestore(&np->lock, flags); } if (pkts < limit) { @@ -2591,13 +2591,15 @@ static int nv_napi_poll(struct net_device *dev, int *budget) netif_rx_complete(dev); /* re-enable receive interrupts */ - spin_lock_irq(&np->lock); + spin_lock_irqsave(&np->lock, flags); + np->irqmask |= NVREG_IRQ_RX_ALL; if (np->msi_flags & NV_MSI_X_ENABLED) writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); else writel(np->irqmask, base + NvRegIrqMask); - spin_unlock_irq(&np->lock); + + spin_unlock_irqrestore(&np->lock, flags); return 0; } else { /* used up our quantum, so reschedule */ diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c index 4a97024061e..9074f76ee2b 100644 --- a/drivers/net/ibm_emac/ibm_emac_phy.c +++ b/drivers/net/ibm_emac/ibm_emac_phy.c @@ -309,7 +309,7 @@ int mii_phy_probe(struct mii_phy *phy, int address) { struct mii_phy_def *def; int i; - u32 id; + int id; phy->autoneg = AUTONEG_DISABLE; phy->advertising = 0; @@ -324,6 +324,8 @@ int mii_phy_probe(struct mii_phy *phy, int address) /* Read ID and find matching entry */ id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2); + if (id < 0) + return -ENODEV; for (i = 0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 94ac168be59..07cf574197e 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -199,8 +199,6 @@ struct myri10ge_priv { unsigned long serial_number; int vendor_specific_offset; int fw_multicast_support; - u32 devctl; - u16 msi_flags; u32 read_dma; u32 write_dma; u32 read_write_dma; @@ -228,7 +226,7 @@ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); static int myri10ge_msi = 1; /* enable msi by default */ -module_param(myri10ge_msi, int, S_IRUGO); +module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); static int myri10ge_intr_coal_delay = 25; @@ -721,12 +719,10 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); - if (!mgp->msi_enabled) { - status |= myri10ge_send_cmd - (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); - mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); + status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, + &cmd, 0); + mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); - } status |= myri10ge_send_cmd (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); @@ -1619,6 +1615,41 @@ static void myri10ge_free_rings(struct net_device *dev) mgp->tx.req_list = NULL; } +static int myri10ge_request_irq(struct myri10ge_priv *mgp) +{ + struct pci_dev *pdev = mgp->pdev; + int status; + + if (myri10ge_msi) { + status = pci_enable_msi(pdev); + if (status != 0) + dev_err(&pdev->dev, + "Error %d setting up MSI; falling back to xPIC\n", + status); + else + mgp->msi_enabled = 1; + } else { + mgp->msi_enabled = 0; + } + status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, + mgp->dev->name, mgp); + if (status != 0) { + dev_err(&pdev->dev, "failed to allocate IRQ\n"); + if (mgp->msi_enabled) + pci_disable_msi(pdev); + } + return status; +} + +static void myri10ge_free_irq(struct myri10ge_priv *mgp) +{ + struct pci_dev *pdev = mgp->pdev; + + free_irq(pdev->irq, mgp); + if (mgp->msi_enabled) + pci_disable_msi(pdev); +} + static int myri10ge_open(struct net_device *dev) { struct myri10ge_priv *mgp; @@ -1634,10 +1665,13 @@ static int myri10ge_open(struct net_device *dev) status = myri10ge_reset(mgp); if (status != 0) { printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); - mgp->running = MYRI10GE_ETH_STOPPED; - return -ENXIO; + goto abort_with_nothing; } + status = myri10ge_request_irq(mgp); + if (status != 0) + goto abort_with_nothing; + /* decide what small buffer size to use. For good TCP rx * performance, it is important to not receive 1514 byte * frames into jumbo buffers, as it confuses the socket buffer @@ -1677,7 +1711,7 @@ static int myri10ge_open(struct net_device *dev) "myri10ge: %s: failed to get ring sizes or locations\n", dev->name); mgp->running = MYRI10GE_ETH_STOPPED; - return -ENXIO; + goto abort_with_irq; } if (mgp->mtrr >= 0) { @@ -1708,7 +1742,7 @@ static int myri10ge_open(struct net_device *dev) status = myri10ge_allocate_rings(dev); if (status != 0) - goto abort_with_nothing; + goto abort_with_irq; /* now give firmware buffers sizes, and MTU */ cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; @@ -1771,6 +1805,9 @@ static int myri10ge_open(struct net_device *dev) abort_with_rings: myri10ge_free_rings(dev); +abort_with_irq: + myri10ge_free_irq(mgp); + abort_with_nothing: mgp->running = MYRI10GE_ETH_STOPPED; return -ENOMEM; @@ -1807,7 +1844,7 @@ static int myri10ge_close(struct net_device *dev) printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); netif_tx_disable(dev); - + myri10ge_free_irq(mgp); myri10ge_free_rings(dev); mgp->running = MYRI10GE_ETH_STOPPED; @@ -2481,34 +2518,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) } } -static void myri10ge_save_state(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int cap; - - pci_save_state(pdev); - /* now save PCIe and MSI state that Linux will not - * save for us */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl); - cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); - pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags); -} - -static void myri10ge_restore_state(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int cap; - - /* restore PCIe and MSI state that linux will not */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl); - cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); - pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags); - - pci_restore_state(pdev); -} - #ifdef CONFIG_PM static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) @@ -2529,11 +2538,10 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) rtnl_unlock(); } myri10ge_dummy_rdma(mgp, 0); - free_irq(pdev->irq, mgp); - myri10ge_save_state(mgp); + pci_save_state(pdev); pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; + + return pci_set_power_state(pdev, pci_choose_state(pdev, state)); } static int myri10ge_resume(struct pci_dev *pdev) @@ -2555,34 +2563,33 @@ static int myri10ge_resume(struct pci_dev *pdev) mgp->dev->name); return -EIO; } - myri10ge_restore_state(mgp); + + status = pci_restore_state(pdev); + if (status) + return status; status = pci_enable_device(pdev); - if (status < 0) { + if (status) { dev_err(&pdev->dev, "failed to enable device\n"); - return -EIO; + return status; } pci_set_master(pdev); - status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, - netdev->name, mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to allocate IRQ\n"); - goto abort_with_enabled; - } - myri10ge_reset(mgp); myri10ge_dummy_rdma(mgp, 1); /* Save configuration space to be restored if the * nic resets due to a parity error */ - myri10ge_save_state(mgp); + pci_save_state(pdev); if (netif_running(netdev)) { rtnl_lock(); - myri10ge_open(netdev); + status = myri10ge_open(netdev); rtnl_unlock(); + if (status != 0) + goto abort_with_enabled; + } netif_device_attach(netdev); @@ -2640,7 +2647,11 @@ static void myri10ge_watchdog(struct work_struct *work) * when the driver was loaded, or the last time the * nic was resumed from power saving mode. */ - myri10ge_restore_state(mgp); + pci_restore_state(mgp->pdev); + + /* save state again for accounting reasons */ + pci_save_state(mgp->pdev); + } else { /* if we get back -1's from our slot, perhaps somebody * powered off our card. Don't try to reset it in @@ -2856,23 +2867,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto abort_with_firmware; } - if (myri10ge_msi) { - status = pci_enable_msi(pdev); - if (status != 0) - dev_err(&pdev->dev, - "Error %d setting up MSI; falling back to xPIC\n", - status); - else - mgp->msi_enabled = 1; - } - - status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, - netdev->name, mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to allocate IRQ\n"); - goto abort_with_firmware; - } - pci_set_drvdata(pdev, mgp); if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; @@ -2896,7 +2890,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Save configuration space to be restored if the * nic resets due to a parity error */ - myri10ge_save_state(mgp); + pci_save_state(pdev); /* Setup the watchdog timer */ setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, @@ -2907,19 +2901,16 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) status = register_netdev(netdev); if (status != 0) { dev_err(&pdev->dev, "register_netdev failed: %d\n", status); - goto abort_with_irq; + goto abort_with_state; } - dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", - (mgp->msi_enabled ? "MSI" : "xPIC"), + dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n", pdev->irq, mgp->tx.boundary, mgp->fw_name, (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); return 0; -abort_with_irq: - free_irq(pdev->irq, mgp); - if (mgp->msi_enabled) - pci_disable_msi(pdev); +abort_with_state: + pci_restore_state(pdev); abort_with_firmware: myri10ge_dummy_rdma(mgp, 0); @@ -2970,12 +2961,12 @@ static void myri10ge_remove(struct pci_dev *pdev) flush_scheduled_work(); netdev = mgp->dev; unregister_netdev(netdev); - free_irq(pdev->irq, mgp); - if (mgp->msi_enabled) - pci_disable_msi(pdev); myri10ge_dummy_rdma(mgp, 0); + /* avoid a memory leak */ + pci_restore_state(pdev); + bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); dma_free_coherent(&pdev->dev, bytes, mgp->rx_done.entry, mgp->rx_done.bus); diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index b5410bee5f2..6490acf0530 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,7 +63,7 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "1" +#define NETXEN_NIC_BUILD_NO "4" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 #define _NETXEN_NIC_LINUX_SUBVERSION 2 @@ -137,7 +137,7 @@ extern struct workqueue_struct *netxen_workq; #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START #define MAX_RX_BUFFER_LENGTH 1760 -#define MAX_RX_JUMBO_BUFFER_LENGTH 9046 +#define MAX_RX_JUMBO_BUFFER_LENGTH 8062 #define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) #define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) #define RX_JUMBO_DMA_MAP_LEN \ @@ -199,9 +199,9 @@ enum { (RCV_DESC_NORMAL))) #define MAX_CMD_DESCRIPTORS 1024 -#define MAX_RCV_DESCRIPTORS 32768 -#define MAX_JUMBO_RCV_DESCRIPTORS 4096 -#define MAX_LRO_RCV_DESCRIPTORS 2048 +#define MAX_RCV_DESCRIPTORS 16384 +#define MAX_JUMBO_RCV_DESCRIPTORS 1024 +#define MAX_LRO_RCV_DESCRIPTORS 64 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS @@ -852,8 +852,6 @@ struct netxen_adapter { spinlock_t tx_lock; spinlock_t lock; struct work_struct watchdog_task; - struct work_struct tx_timeout_task; - struct net_device *netdev; struct timer_list watchdog_timer; u32 curr_window; @@ -887,7 +885,6 @@ struct netxen_adapter { struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; int is_up; - int number; struct netxen_dummy_dma dummy_dma; /* Context interface shared between card and host */ @@ -950,6 +947,7 @@ struct netxen_port { struct pci_dev *pdev; struct net_device_stats net_stats; struct netxen_port_stats stats; + struct work_struct tx_timeout_task; }; #define PCI_OFFSET_FIRST_RANGE(adapter, off) \ @@ -1027,14 +1025,6 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); -int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len); -int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len); -int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size); -int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); @@ -1067,9 +1057,6 @@ void netxen_tso_check(struct netxen_adapter *adapter, struct cmd_desc_type0 *desc, struct sk_buff *skb); int netxen_nic_hw_resources(struct netxen_adapter *adapter); void netxen_nic_clear_stats(struct netxen_adapter *adapter); -int -netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, - struct netxen_port *port); int netxen_nic_rx_has_work(struct netxen_adapter *adapter); int netxen_nic_tx_has_work(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 2ab4885cc95..34044616b3c 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -42,7 +42,6 @@ #include "netxen_nic_hw.h" #include "netxen_nic.h" #include "netxen_nic_phan_reg.h" -#include "netxen_nic_ioctl.h" struct netxen_nic_stats { char stat_string[ETH_GSTRING_LEN]; @@ -79,8 +78,7 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)}, }; -#define NETXEN_NIC_STATS_LEN \ - sizeof(netxen_nic_gstrings_stats) / sizeof(struct netxen_nic_stats) +#define NETXEN_NIC_STATS_LEN ARRAY_SIZE(netxen_nic_gstrings_stats) static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_offline", "EEPROM_Test_offline", @@ -711,7 +709,6 @@ netxen_nic_get_ethtool_stats(struct net_device *dev, (netxen_nic_gstrings_stats[index].sizeof_stat == sizeof(u64)) ? *(u64 *) p : *(u32 *) p; } - } struct ethtool_ops netxen_nic_ethtool_ops = { diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9147b6048df..c0c31d1914a 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -376,7 +376,7 @@ void netxen_tso_check(struct netxen_adapter *adapter, ((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)); netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); - } else if (skb->ip_summed == CHECKSUM_COMPLETE) { + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb->nh.iph->protocol == IPPROTO_TCP) { netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); } else if (skb->nh.iph->protocol == IPPROTO_UDP) { @@ -997,297 +997,3 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) fw_major, fw_minor); } -int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off) -{ - int data; - netxen_nic_hw_read_wx(adapter, off, &data, 4); - return data; -} - -int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len) -{ - void *addr; - u64 offset = off; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (ADDR_IN_WINDOW1(off)) { - addr = NETXEN_CRB_NORMALIZE(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - offset = NETXEN_CRB_NORMAL(off); - mem_page = offset & PAGE_MASK; - if (mem_page != ((offset + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += offset & (PAGE_SIZE - 1); - } - } else { - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - if (mem_page != ((off + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - netxen_nic_pci_change_crbwindow(adapter, 0); - } - switch (len) { - case 1: - writeb(*(u8 *) data, addr); - break; - case 2: - writew(*(u16 *) data, addr); - break; - case 4: - writel(*(u32 *) data, addr); - break; - case 8: - writeq(*(u64 *) data, addr); - break; - default: - DPRINTK(INFO, - "writing data %lx to offset %llx, num words=%d\n", - *(unsigned long *)data, off, (len >> 3)); - - netxen_nic_hw_block_write64((u64 __iomem *) data, addr, - (len >> 3)); - break; - } - - if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); - if (mem_ptr) - iounmap(mem_ptr); - return 0; -} - -int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len) -{ - void *addr; - u64 offset; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (ADDR_IN_WINDOW1(off)) { - addr = NETXEN_CRB_NORMALIZE(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - offset = NETXEN_CRB_NORMAL(off); - mem_page = offset & PAGE_MASK; - if (mem_page != ((offset + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - *(u8 *) data = 0; - return 1; - } - addr = mem_ptr; - addr += offset & (PAGE_SIZE - 1); - } - } else { - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - if (mem_page != ((off + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) - return 1; - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - netxen_nic_pci_change_crbwindow(adapter, 0); - } - switch (len) { - case 1: - *(u8 *) data = readb(addr); - break; - case 2: - *(u16 *) data = readw(addr); - break; - case 4: - *(u32 *) data = readl(addr); - break; - case 8: - *(u64 *) data = readq(addr); - break; - default: - netxen_nic_hw_block_read64((u64 __iomem *) data, addr, - (len >> 3)); - break; - } - if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); - if (mem_ptr) - iounmap(mem_ptr); - return 0; -} - -int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int size) -{ - void *addr; - int ret = 0; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (data == NULL || off > (128 * 1024 * 1024)) { - printk(KERN_ERR "%s: data: %p off:%llx\n", - netxen_nic_driver_name, data, off); - return 1; - } - off = netxen_nic_pci_set_window(adapter, off); - /* Corner case : Malicious user tried to break the driver by reading - last few bytes in ranges and tries to read further addresses. - */ - if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { - printk(KERN_ERR "%s: Invalid access to memory address range" - " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, - off + size); - return 1; - } - addr = pci_base_offset(adapter, off); - DPRINTK(INFO, "writing data %llx to offset %llx\n", - *(unsigned long long *)data, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - /* Map two pages whenever user tries to access addresses in two - consecutive pages. - */ - if (mem_page != ((off + size - 1) & PAGE_MASK)) - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - switch (size) { - case 1: - writeb(*(u8 *) data, addr); - break; - case 2: - writew(*(u16 *) data, addr); - break; - case 4: - writel(*(u32 *) data, addr); - break; - case 8: - writeq(*(u64 *) data, addr); - break; - default: - DPRINTK(INFO, - "writing data %lx to offset %llx, num words=%d\n", - *(unsigned long *)data, off, (size >> 3)); - - netxen_nic_hw_block_write64((u64 __iomem *) data, addr, - (size >> 3)); - break; - } - - if (mem_ptr) - iounmap(mem_ptr); - DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data); - - return ret; -} - -int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size) -{ - void *addr; - int ret = 0; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (data == NULL || off > (128 * 1024 * 1024)) { - printk(KERN_ERR "%s: data: %p off:%llx\n", - netxen_nic_driver_name, data, off); - return 1; - } - off = netxen_nic_pci_set_window(adapter, off); - /* Corner case : Malicious user tried to break the driver by reading - last few bytes in ranges and tries to read further addresses. - */ - if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { - printk(KERN_ERR "%s: Invalid access to memory address range" - " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, - off + size); - return 1; - } - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - /* Map two pages whenever user tries to access addresses in two - consecutive pages. - */ - if (mem_page != ((off + size - 1) & PAGE_MASK)) - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - *(u8 *) data = 0; - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - switch (size) { - case 1: - *(u8 *) data = readb(addr); - break; - case 2: - *(u16 *) data = readw(addr); - break; - case 4: - *(u32 *) data = readl(addr); - break; - case 8: - *(u64 *) data = readq(addr); - break; - default: - netxen_nic_hw_block_read64((u64 __iomem *) data, addr, - (size >> 3)); - break; - } - - if (mem_ptr) - iounmap(mem_ptr); - DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data); - - return ret; -} diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 869725f0bb1..c3e41f36855 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -35,7 +35,6 @@ #include <linux/delay.h> #include "netxen_nic.h" #include "netxen_nic_hw.h" -#include "netxen_nic_ioctl.h" #include "netxen_nic_phan_reg.h" struct crb_addr_pair { @@ -928,7 +927,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) } netxen_process_rcv(adapter, ctxid, desc); netxen_clear_sts_owner(desc); - netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); + netxen_set_sts_owner(desc, cpu_to_le16(STATUS_OWNER_PHANTOM)); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } @@ -1023,7 +1022,7 @@ int netxen_process_cmd_ring(unsigned long data) && netif_carrier_ok(port->netdev)) && ((jiffies - port->netdev->trans_start) > port->netdev->watchdog_timeo)) { - SCHEDULE_WORK(&port->adapter->tx_timeout_task); + SCHEDULE_WORK(&port->tx_timeout_task); } last_consumer = get_next_index(last_consumer, @@ -1138,13 +1137,13 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) */ dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = dma; + pdesc->addr_buffer = cpu_to_le64(dma); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; buffer->dma = dma; /* make a rcv descriptor */ - pdesc->reference_handle = buffer->ref_handle; - pdesc->buffer_length = rcv_desc->dma_size; + pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); + pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); DPRINTK(INFO, "done writing descripter\n"); producer = get_next_index(producer, rcv_desc->max_rx_desc_count); @@ -1232,8 +1231,8 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, PCI_DMA_FROMDEVICE); /* make a rcv descriptor */ - pdesc->reference_handle = le16_to_cpu(buffer->ref_handle); - pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size); + pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); + pdesc->buffer_length = cpu_to_le16(rcv_desc->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); DPRINTK(INFO, "done writing descripter\n"); producer = @@ -1273,52 +1272,6 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter) return 0; } -int -netxen_nic_fill_statistics(struct netxen_adapter *adapter, - struct netxen_port *port, - struct netxen_statistics *netxen_stats) -{ - void __iomem *addr; - - if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { - netxen_nic_pci_change_crbwindow(adapter, 0); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT, - &(netxen_stats->tx_bytes)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT, - &(netxen_stats->tx_packets)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT, - &(netxen_stats->rx_bytes)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT, - &(netxen_stats->rx_packets)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT, - &(netxen_stats->rx_errors)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT, - &(netxen_stats->rx_crc_errors)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, - &(netxen_stats-> - rx_long_length_error)); - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, - &(netxen_stats-> - rx_short_length_error)); - - netxen_nic_pci_change_crbwindow(adapter, 1); - } else { - spin_lock_bh(&adapter->tx_lock); - netxen_stats->tx_bytes = port->stats.txbytes; - netxen_stats->tx_packets = port->stats.xmitedframes + - port->stats.xmitfinished; - netxen_stats->rx_bytes = port->stats.rxbytes; - netxen_stats->rx_packets = port->stats.no_rcv; - netxen_stats->rx_errors = port->stats.rcvdbadskb; - netxen_stats->tx_errors = port->stats.nocmddescriptor; - netxen_stats->rx_short_length_error = port->stats.uplcong; - netxen_stats->rx_long_length_error = port->stats.uphcong; - netxen_stats->rx_crc_errors = 0; - netxen_stats->rx_mac_errors = 0; - spin_unlock_bh(&adapter->tx_lock); - } - return 0; -} void netxen_nic_clear_stats(struct netxen_adapter *adapter) { @@ -1332,193 +1285,3 @@ void netxen_nic_clear_stats(struct netxen_adapter *adapter) } } -int -netxen_nic_clear_statistics(struct netxen_adapter *adapter, - struct netxen_port *port) -{ - int data = 0; - - netxen_nic_pci_change_crbwindow(adapter, 0); - - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_BYTE_CNT, &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_FRAME_CNT, - &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_BYTE_CNT, &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_FRAME_CNT, - &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_AGGR_ERROR_CNT, - &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_CRC_ERROR_CNT, - &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, - &data); - netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, - &data); - - netxen_nic_pci_change_crbwindow(adapter, 1); - netxen_nic_clear_stats(adapter); - return 0; -} - -int -netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, - struct netxen_port *port) -{ - struct netxen_nic_ioctl_data data; - struct netxen_nic_ioctl_data *up_data; - int retval = 0; - struct netxen_statistics netxen_stats; - - up_data = (void *)u_data; - - DPRINTK(INFO, "doing ioctl for %p\n", adapter); - if (copy_from_user(&data, (void __user *)up_data, sizeof(data))) { - /* evil user tried to crash the kernel */ - DPRINTK(ERR, "bad copy from userland: %d\n", (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - - /* Shouldn't access beyond legal limits of "char u[64];" member */ - if (!data.ptr && (data.size > sizeof(data.u))) { - /* evil user tried to crash the kernel */ - DPRINTK(ERR, "bad size: %d\n", data.size); - retval = -EFAULT; - goto error_out; - } - - switch (data.cmd) { - case netxen_nic_cmd_pci_read: - if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off, - &(data.u), data.size))) - goto error_out; - if (copy_to_user - ((void __user *)&(up_data->u), &(data.u), data.size)) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - data.rv = 0; - break; - - case netxen_nic_cmd_pci_write: - if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off, - &(data.u), data.size))) - goto error_out; - data.rv = 0; - break; - - case netxen_nic_cmd_pci_mem_read: - if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u), - data.size)) { - DPRINTK(ERR, "Failed to read the data.\n"); - retval = -EFAULT; - goto error_out; - } - if (copy_to_user - ((void __user *)&(up_data->u), &(data.u), data.size)) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - data.rv = 0; - break; - - case netxen_nic_cmd_pci_mem_write: - if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off, - &(data.u), - data.size))) - goto error_out; - data.rv = 0; - break; - - case netxen_nic_cmd_pci_config_read: - switch (data.size) { - case 1: - data.rv = pci_read_config_byte(adapter->ahw.pdev, - data.off, - (char *)&(data.u)); - break; - case 2: - data.rv = pci_read_config_word(adapter->ahw.pdev, - data.off, - (short *)&(data.u)); - break; - case 4: - data.rv = pci_read_config_dword(adapter->ahw.pdev, - data.off, - (u32 *) & (data.u)); - break; - } - if (copy_to_user - ((void __user *)&(up_data->u), &(data.u), data.size)) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - break; - - case netxen_nic_cmd_pci_config_write: - switch (data.size) { - case 1: - data.rv = pci_write_config_byte(adapter->ahw.pdev, - data.off, - *(char *)&(data.u)); - break; - case 2: - data.rv = pci_write_config_word(adapter->ahw.pdev, - data.off, - *(short *)&(data.u)); - break; - case 4: - data.rv = pci_write_config_dword(adapter->ahw.pdev, - data.off, - *(u32 *) & (data.u)); - break; - } - break; - - case netxen_nic_cmd_get_stats: - data.rv = - netxen_nic_fill_statistics(adapter, port, &netxen_stats); - if (copy_to_user - ((void __user *)(up_data->ptr), (void *)&netxen_stats, - sizeof(struct netxen_statistics))) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(netxen_stats)); - retval = -EFAULT; - goto error_out; - } - up_data->rv = data.rv; - break; - - case netxen_nic_cmd_clear_stats: - data.rv = netxen_nic_clear_statistics(adapter, port); - up_data->rv = data.rv; - break; - - case netxen_nic_cmd_get_version: - if (copy_to_user - ((void __user *)&(up_data->u), NETXEN_NIC_LINUX_VERSIONID, - sizeof(NETXEN_NIC_LINUX_VERSIONID))) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - break; - - default: - DPRINTK(INFO, "bad command %d for %p\n", data.cmd, adapter); - retval = -EOPNOTSUPP; - goto error_out; - } - put_user(data.rv, (&(up_data->rv))); - DPRINTK(INFO, "done ioctl for %p well.\n", adapter); - - error_out: - return retval; -} diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h deleted file mode 100644 index 1221fa52755..00000000000 --- a/drivers/net/netxen/netxen_nic_ioctl.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2003 - 2006 NetXen, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE. - * - * Contact Information: - * info@netxen.com - * NetXen, - * 3965 Freedom Circle, Fourth floor, - * Santa Clara, CA 95054 - */ - -#ifndef __NETXEN_NIC_IOCTL_H__ -#define __NETXEN_NIC_IOCTL_H__ - -#include <linux/sockios.h> - -#define NETXEN_CMD_START SIOCDEVPRIVATE -#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) -#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) -#define NETXEN_NIC_NAME_LEN 16 -#define NETXEN_NIC_NAME_RSP "NETXEN-UNM" - -typedef enum { - netxen_nic_cmd_none = 0, - netxen_nic_cmd_pci_read, - netxen_nic_cmd_pci_write, - netxen_nic_cmd_pci_mem_read, - netxen_nic_cmd_pci_mem_write, - netxen_nic_cmd_pci_config_read, - netxen_nic_cmd_pci_config_write, - netxen_nic_cmd_get_stats, - netxen_nic_cmd_clear_stats, - netxen_nic_cmd_get_version -} netxen_nic_ioctl_cmd_t; - -struct netxen_nic_ioctl_data { - u32 cmd; - u32 unused1; - u64 off; - u32 size; - u32 rv; - char u[64]; - void *ptr; -}; - -struct netxen_statistics { - u64 rx_packets; - u64 tx_packets; - u64 rx_bytes; - u64 rx_errors; - u64 tx_bytes; - u64 tx_errors; - u64 rx_crc_errors; - u64 rx_short_length_error; - u64 rx_long_length_error; - u64 rx_mac_errors; -}; - -#endif /* __NETXEN_NIC_IOCTL_H_ */ diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 1b45f50fa6a..06847d4252c 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -157,7 +157,8 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter) for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { linkup = val & 1; if (linkup != (qg_linksup & 1)) { - printk(KERN_INFO "%s: PORT %d link %s\n", + printk(KERN_INFO "%s: %s PORT %d link %s\n", + adapter->port[portno]->netdev->name, netxen_nic_driver_name, portno, ((linkup == 0) ? "down" : "up")); netxen_indicate_link_status(adapter, portno, linkup); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 575b71b6720..8a5792fea77 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -38,7 +38,6 @@ #include "netxen_nic.h" #define DEFINE_GLOBAL_RECV_CRB #include "netxen_nic_phan_reg.h" -#include "netxen_nic_ioctl.h" #include <linux/dma-mapping.h> #include <linux/vmalloc.h> @@ -53,8 +52,6 @@ char netxen_nic_driver_name[] = "netxen-nic"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " NETXEN_NIC_LINUX_VERSIONID; -struct netxen_adapter *g_adapter = NULL; - #define NETXEN_NETDEV_WEIGHT 120 #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 @@ -75,8 +72,6 @@ static void netxen_tx_timeout(struct net_device *netdev); static void netxen_tx_timeout_task(struct work_struct *work); static void netxen_watchdog(unsigned long); static int netxen_handle_int(struct netxen_adapter *, struct net_device *); -static int netxen_nic_ioctl(struct net_device *netdev, - struct ifreq *ifr, int cmd); static int netxen_nic_poll(struct net_device *dev, int *budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void netxen_nic_poll_controller(struct net_device *netdev); @@ -90,6 +85,8 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { {PCI_DEVICE(0x4040, 0x0003)}, {PCI_DEVICE(0x4040, 0x0004)}, {PCI_DEVICE(0x4040, 0x0005)}, + {PCI_DEVICE(0x4040, 0x0024)}, + {PCI_DEVICE(0x4040, 0x0025)}, {0,} }; @@ -129,7 +126,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct netxen_cmd_buffer *cmd_buf_arr = NULL; u64 mac_addr[FLASH_NUM_PORTS + 1]; int valid_mac = 0; - static int netxen_cards_found = 0; printk(KERN_INFO "%s \n", netxen_nic_driver_string); /* In current scheme, we use only PCI function 0 */ @@ -220,9 +216,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_dbunmap; } - if (netxen_cards_found == 0) { - g_adapter = adapter; - } adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; @@ -383,7 +376,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->set_multicast_list = netxen_nic_set_multi; netdev->set_mac_address = netxen_nic_set_mac; netdev->change_mtu = netxen_nic_change_mtu; - netdev->do_ioctl = netxen_nic_ioctl; netdev->tx_timeout = netxen_tx_timeout; netdev->watchdog_timeo = HZ; @@ -428,8 +420,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr); } } - adapter->netdev = netdev; - INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); + INIT_WORK(&port->tx_timeout_task, netxen_tx_timeout_task); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -444,6 +435,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->port[i] = port; } + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); + netxen_pinit_from_rom(adapter, 0); + udelay(500); + netxen_load_firmware(adapter); + netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); /* * delay a while to ensure that the Pegs are up & running. * Otherwise, we might see some flaky behaviour. @@ -461,7 +457,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - adapter->number = netxen_cards_found; adapter->driver_mismatch = 0; return 0; @@ -531,6 +526,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_nic_stop_all_ports(adapter); /* leave the hw in the same state as reboot */ + netxen_pinit_from_rom(adapter, 0); + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); netxen_load_firmware(adapter); netxen_free_adapter_offload(adapter); @@ -821,8 +818,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = skb_shinfo(skb)->gso_size; - hwdesc->mss = skb_shinfo(skb)->gso_size; + pbuf->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); } else { pbuf->mss = 0; hwdesc->mss = 0; @@ -956,11 +953,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) static void netxen_watchdog(unsigned long v) { struct netxen_adapter *adapter = (struct netxen_adapter *)v; - if (adapter != g_adapter) { - printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n", - __FUNCTION__, adapter, g_adapter); - return; - } SCHEDULE_WORK(&adapter->watchdog_task); } @@ -969,23 +961,23 @@ static void netxen_tx_timeout(struct net_device *netdev) { struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); - SCHEDULE_WORK(&port->adapter->tx_timeout_task); + SCHEDULE_WORK(&port->tx_timeout_task); } static void netxen_tx_timeout_task(struct work_struct *work) { - struct netxen_adapter *adapter = - container_of(work, struct netxen_adapter, tx_timeout_task); - struct net_device *netdev = adapter->netdev; + struct netxen_port *port = + container_of(work, struct netxen_port, tx_timeout_task); + struct net_device *netdev = port->netdev; unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, netdev->name); - spin_lock_irqsave(&adapter->lock, flags); + spin_lock_irqsave(&port->adapter->lock, flags); netxen_nic_close(netdev); netxen_nic_open(netdev); - spin_unlock_irqrestore(&adapter->lock, flags); + spin_unlock_irqrestore(&port->adapter->lock, flags); netdev->trans_start = jiffies; netif_wake_queue(netdev); } @@ -1137,47 +1129,6 @@ static void netxen_nic_poll_controller(struct net_device *netdev) enable_irq(adapter->irq); } #endif -/* - * netxen_nic_ioctl () We provide the tcl/phanmon support through these - * ioctls. - */ -static int -netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - int err = 0; - unsigned long nr_bytes = 0; - struct netxen_port *port = netdev_priv(netdev); - struct netxen_adapter *adapter = port->adapter; - char dev_name[NETXEN_NIC_NAME_LEN]; - - DPRINTK(INFO, "doing ioctl for %s\n", netdev->name); - switch (cmd) { - case NETXEN_NIC_CMD: - err = netxen_nic_do_ioctl(adapter, (void *)ifr->ifr_data, port); - break; - - case NETXEN_NIC_NAME: - DPRINTK(INFO, "ioctl cmd for NetXen\n"); - if (ifr->ifr_data) { - sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, - port->portnum); - nr_bytes = - copy_to_user((char __user *)ifr->ifr_data, dev_name, - NETXEN_NIC_NAME_LEN); - if (nr_bytes) - err = -EIO; - - } - break; - - default: - DPRINTK(INFO, "ioctl cmd %x not supported\n", cmd); - err = -EOPNOTSUPP; - break; - } - - return err; -} static struct pci_driver netxen_driver = { .name = netxen_nic_driver_name, diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index f83b41d4cb0..577babd4c93 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -225,7 +225,6 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); static int rx_copybreak = 200; static int use_dac; -static int ignore_parity_err; static struct { u32 msg_enable; } debug = { -1 }; @@ -471,8 +470,6 @@ module_param(use_dac, int, 0); MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); -module_param_named(ignore_parity_err, ignore_parity_err, bool, 0); -MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false"); MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); @@ -1885,7 +1882,6 @@ static void rtl8169_hw_start(struct net_device *dev) (tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03) || (tp->mac_version == RTL_GIGA_MAC_VER_04)) - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl8169_set_rx_tx_config_registers(tp); cmd = RTL_R16(CPlusCmd); @@ -2388,7 +2384,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) * * Feel free to adjust to your needs. */ - if (ignore_parity_err) + if (pdev->broken_parity_status) pci_cmd &= ~PCI_COMMAND_PARITY; else pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8a39376f87d..deedfd5f822 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2920,6 +2920,7 @@ static int skge_poll(struct net_device *dev, int *budget) struct skge_hw *hw = skge->hw; struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; + unsigned long flags; int to_do = min(dev->quota, *budget); int work_done = 0; @@ -2957,12 +2958,12 @@ static int skge_poll(struct net_device *dev, int *budget) if (work_done >= to_do) return 1; /* not done */ - spin_lock_irq(&hw->hw_lock); + spin_lock_irqsave(&hw->hw_lock, flags); __netif_rx_complete(dev); hw->intr_mask |= irqmask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); skge_read32(hw, B0_IMSK); - spin_unlock_irq(&hw->hw_lock); + spin_unlock_irqrestore(&hw->hw_lock, flags); return 0; } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fb1d2c30c1b..a6601e8d423 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -569,8 +569,8 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) onoff = !onoff; + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); - if (onoff) /* Turn off phy power saving */ reg1 &= ~phy_power[port]; @@ -579,6 +579,7 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) sky2_pci_write32(hw, PCI_DEV_REG1, reg1); sky2_pci_read32(hw, PCI_DEV_REG1); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); udelay(100); } @@ -1511,6 +1512,13 @@ static int sky2_down(struct net_device *dev) imask &= ~portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); + /* + * Both ports share the NAPI poll on port 0, so if necessary undo the + * the disable that is done in dev_close. + */ + if (sky2->port == 0 && hw->ports > 1) + netif_poll_enable(dev); + sky2_gmac_reset(hw, port); /* Stop transmitter */ @@ -3631,6 +3639,29 @@ static int sky2_resume(struct pci_dev *pdev) out: return err; } + +/* BIOS resume runs after device (it's a bug in PM) + * as a temporary workaround on suspend/resume leave MSI disabled + */ +static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state) +{ + struct sky2_hw *hw = pci_get_drvdata(pdev); + + free_irq(pdev->irq, hw); + if (hw->msi) { + pci_disable_msi(pdev); + hw->msi = 0; + } + return 0; +} + +static int sky2_resume_early(struct pci_dev *pdev) +{ + struct sky2_hw *hw = pci_get_drvdata(pdev); + struct net_device *dev = hw->dev[0]; + + return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw); +} #endif static struct pci_driver sky2_driver = { @@ -3641,6 +3672,8 @@ static struct pci_driver sky2_driver = { #ifdef CONFIG_PM .suspend = sky2_suspend, .resume = sky2_resume, + .suspend_late = sky2_suspend_late, + .resume_early = sky2_resume_early, #endif }; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 4587f23f4e4..8e5d82051bd 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -265,15 +265,19 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status); static int velocity_suspend(struct pci_dev *pdev, pm_message_t state); static int velocity_resume(struct pci_dev *pdev); +static DEFINE_SPINLOCK(velocity_dev_list_lock); +static LIST_HEAD(velocity_dev_list); + +#endif + +#if defined(CONFIG_PM) && defined(CONFIG_INET) + static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr); static struct notifier_block velocity_inetaddr_notifier = { .notifier_call = velocity_netdev_event, }; -static DEFINE_SPINLOCK(velocity_dev_list_lock); -static LIST_HEAD(velocity_dev_list); - static void velocity_register_notifier(void) { register_inetaddr_notifier(&velocity_inetaddr_notifier); @@ -284,12 +288,12 @@ static void velocity_unregister_notifier(void) unregister_inetaddr_notifier(&velocity_inetaddr_notifier); } -#else /* CONFIG_PM */ +#else #define velocity_register_notifier() do {} while (0) #define velocity_unregister_notifier() do {} while (0) -#endif /* !CONFIG_PM */ +#endif /* * Internal board variants. At the moment we have only one @@ -3292,6 +3296,8 @@ static int velocity_resume(struct pci_dev *pdev) return 0; } +#ifdef CONFIG_INET + static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) { struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; @@ -3312,4 +3318,6 @@ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notifi } return NOTIFY_DONE; } + +#endif #endif diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 00ca704ece3..a08524191b5 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -41,6 +41,8 @@ static void housekeeping_disable(struct zd_mac *mac); static void set_multicast_hash_handler(struct work_struct *work); +static void do_rx(unsigned long mac_ptr); + int zd_mac_init(struct zd_mac *mac, struct net_device *netdev, struct usb_interface *intf) @@ -53,6 +55,10 @@ int zd_mac_init(struct zd_mac *mac, INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); + skb_queue_head_init(&mac->rx_queue); + tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); + tasklet_disable(&mac->rx_tasklet); + ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); zd_chip_init(&mac->chip, netdev, intf); @@ -140,6 +146,8 @@ out: void zd_mac_clear(struct zd_mac *mac) { flush_workqueue(zd_workqueue); + skb_queue_purge(&mac->rx_queue); + tasklet_kill(&mac->rx_tasklet); zd_chip_clear(&mac->chip); ZD_ASSERT(!spin_is_locked(&mac->lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -168,6 +176,8 @@ int zd_mac_open(struct net_device *netdev) struct zd_chip *chip = &mac->chip; int r; + tasklet_enable(&mac->rx_tasklet); + r = zd_chip_enable_int(chip); if (r < 0) goto out; @@ -218,6 +228,8 @@ int zd_mac_stop(struct net_device *netdev) */ zd_chip_disable_rx(chip); + skb_queue_purge(&mac->rx_queue); + tasklet_disable(&mac->rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); @@ -470,13 +482,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) { /* Set RTS rate to highest available basic rate */ - u8 rate = ieee80211softmac_highest_supported_rate(softmac, + u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac, &bssinfo->supported_rates, 1); - rate = rate_to_zd_rate(rate); + hi_rate = rate_to_zd_rate(hi_rate); spin_lock_irqsave(&mac->lock, flags); - if (rate != mac->rts_rate) { - mac->rts_rate = rate; + if (hi_rate != mac->rts_rate) { + mac->rts_rate = hi_rate; need_set_rts_cts = 1; } spin_unlock_irqrestore(&mac->lock, flags); @@ -1072,43 +1084,75 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, return 0; } -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) +static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) { int r; struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct ieee80211_rx_stats stats; const struct rx_status *status; - struct sk_buff *skb; - if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + - IEEE80211_FCS_LEN + sizeof(struct rx_status)) - return -EINVAL; + if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + + IEEE80211_FCS_LEN + sizeof(struct rx_status)) + { + dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", + skb->len); + goto free_skb; + } - r = fill_rx_stats(&stats, &status, mac, buffer, length); - if (r) - return r; + r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); + if (r) { + /* Only packets with rx errors are included here. */ + goto free_skb; + } - length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ - sizeof(struct rx_status); - buffer += ZD_PLCP_HEADER_SIZE; + __skb_pull(skb, ZD_PLCP_HEADER_SIZE); + __skb_trim(skb, skb->len - + (IEEE80211_FCS_LEN + sizeof(struct rx_status))); - update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); + update_qual_rssi(mac, skb->data, skb->len, stats.signal, + status->signal_strength); - r = filter_rx(ieee, buffer, length, &stats); - if (r <= 0) - return r; + r = filter_rx(ieee, skb->data, skb->len, &stats); + if (r <= 0) { + if (r < 0) + dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); + goto free_skb; + } - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) - return -ENOMEM; if (ieee->iw_mode == IW_MODE_MONITOR) - fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac, + fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, &stats, status); - memcpy(skb_put(skb, length), buffer, length); r = ieee80211_rx(ieee, skb, &stats); - if (!r) - dev_kfree_skb_any(skb); + if (r) + return; +free_skb: + /* We are always in a soft irq. */ + dev_kfree_skb(skb); +} + +static void do_rx(unsigned long mac_ptr) +{ + struct zd_mac *mac = (struct zd_mac *)mac_ptr; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) + zd_mac_rx(mac, skb); +} + +int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); + if (!skb) { + dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); + return -ENOMEM; + } + skb_reserve(skb, sizeof(struct zd_rt_hdr)); + memcpy(__skb_put(skb, length), buffer, length); + skb_queue_tail(&mac->rx_queue, skb); + tasklet_schedule(&mac->rx_tasklet); return 0; } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index f0cf05dc7d3..faf4c7828d4 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -138,6 +138,9 @@ struct zd_mac { struct delayed_work set_rts_cts_work; struct delayed_work set_basic_rates_work; + struct tasklet_struct rx_tasklet; + struct sk_buff_head rx_queue; + unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; @@ -193,7 +196,7 @@ int zd_mac_stop(struct net_device *netdev); int zd_mac_set_mac_address(struct net_device *dev, void *p); void zd_mac_set_multicast_list(struct net_device *netdev); -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length); +int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index aa782e88754..605e96e7405 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -598,13 +598,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, n = l+k; if (n > length) return; - zd_mac_rx(mac, buffer+l, k); + zd_mac_rx_irq(mac, buffer+l, k); if (i >= 2) return; l = (n+3) & ~3; } } else { - zd_mac_rx(mac, buffer, length); + zd_mac_rx_irq(mac, buffer, length); } } diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h index d91d88f93c8..ecad55bf016 100644 --- a/include/media/cx2341x.h +++ b/include/media/cx2341x.h @@ -49,7 +49,7 @@ struct cx2341x_mpeg_params { enum v4l2_mpeg_audio_mode_extension audio_mode_extension; enum v4l2_mpeg_audio_emphasis audio_emphasis; enum v4l2_mpeg_audio_crc audio_crc; - u8 audio_properties; + u16 audio_properties; /* video */ enum v4l2_mpeg_video_encoding video_encoding; diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 2b25f5c9500..4bb0ad81017 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -24,6 +24,7 @@ #define _IR_COMMON #include <linux/input.h> +#include <linux/workqueue.h> #define IR_TYPE_RC5 1 #define IR_TYPE_PD 2 /* Pulse distance encoded IR */ diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b3a198c9248..1d2fc89ca56 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -862,17 +862,46 @@ int clear_page_dirty_for_io(struct page *page) { struct address_space *mapping = page_mapping(page); - if (!mapping) - return TestClearPageDirty(page); - - if (TestClearPageDirty(page)) { - if (mapping_cap_account_dirty(mapping)) { - page_mkclean(page); + if (mapping && mapping_cap_account_dirty(mapping)) { + /* + * Yes, Virginia, this is indeed insane. + * + * We use this sequence to make sure that + * (a) we account for dirty stats properly + * (b) we tell the low-level filesystem to + * mark the whole page dirty if it was + * dirty in a pagetable. Only to then + * (c) clean the page again and return 1 to + * cause the writeback. + * + * This way we avoid all nasty races with the + * dirty bit in multiple places and clearing + * them concurrently from different threads. + * + * Note! Normally the "set_page_dirty(page)" + * has no effect on the actual dirty bit - since + * that will already usually be set. But we + * need the side effects, and it can help us + * avoid races. + * + * We basically use the page "master dirty bit" + * as a serialization point for all the different + * threads doing their things. + * + * FIXME! We still have a race here: if somebody + * adds the page back to the page tables in + * between the "page_mkclean()" and the "TestClearPageDirty()", + * we might have it mapped without the dirty bit set. + */ + if (page_mkclean(page)) + set_page_dirty(page); + if (TestClearPageDirty(page)) { dec_zone_page_state(page, NR_FILE_DIRTY); + return 1; } - return 1; + return 0; } - return 0; + return TestClearPageDirty(page); } EXPORT_SYMBOL(clear_page_dirty_for_io); diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index e3f37fdda65..a824852909e 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -167,7 +167,7 @@ static void ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context) { struct ieee80211softmac_device *mac = ieee80211_priv(dev); - ieee80211softmac_assoc_work((void*)mac); + ieee80211softmac_assoc_work(&mac->associnfo.work.work); } static void @@ -177,7 +177,7 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void switch (event_type) { case IEEE80211SOFTMAC_EVENT_AUTHENTICATED: - ieee80211softmac_assoc_work((void*)mac); + ieee80211softmac_assoc_work(&mac->associnfo.work.work); break; case IEEE80211SOFTMAC_EVENT_AUTH_FAILED: case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT: diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 480d72c7a42..fa2f7da606a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); - mutex_lock(&mac->associnfo.mutex); + mutex_unlock(&mac->associnfo.mutex); return err; } |