diff options
Diffstat (limited to 'drivers')
60 files changed, 1297 insertions, 1545 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 3599ab2506d..e6738bcbe5a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -24,8 +24,6 @@ #include "base.h" #include "power/power.h" -extern const char *kobject_actions[]; - int (*platform_notify)(struct device * dev) = NULL; int (*platform_notify_remove)(struct device * dev) = NULL; @@ -680,8 +678,7 @@ static int device_add_class_symlinks(struct device *dev) if (error) goto out_subsys; } - /* only bus-device parents get a "device"-link */ - if (dev->parent && dev->parent->bus) { + if (dev->parent) { error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); if (error) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 53f0ee6f301..b24efd4e3e3 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -232,6 +232,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) /** * firmware_data_write - write method for firmware * @kobj: kobject for the device + * @bin_attr: bin_attr structure * @buffer: buffer being written * @offset: buffer offset for write in total data store area * @count: buffer size diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index 420c1380f5c..01d07862ea8 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -506,6 +506,7 @@ int c2_alloc_qp(struct c2_dev *c2dev, qp->send_sgl_depth = qp_attrs->cap.max_send_sge; qp->rdma_write_sgl_depth = qp_attrs->cap.max_send_sge; qp->recv_sgl_depth = qp_attrs->cap.max_recv_sge; + init_waitqueue_head(&qp->wait); /* Initialize the SQ MQ */ q_size = be32_to_cpu(reply->sq_depth); diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 3725aa8664d..b5e96030531 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -322,6 +322,7 @@ extern int ehca_static_rate; extern int ehca_port_act_time; extern int ehca_use_hp_mr; extern int ehca_scaling_code; +extern int ehca_mr_largepage; struct ipzu_queue_resp { u32 qe_size; /* queue entry size */ diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index c1b868b79d6..d97eda3e1da 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -40,10 +40,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <rdma/ib_umem.h> - #include <asm/current.h> +#include <rdma/ib_umem.h> + #include "ehca_iverbs.h" #include "ehca_mrmw.h" #include "hcp_if.h" @@ -64,8 +64,6 @@ enum ehca_mr_pgsize { EHCA_MR_PGSIZE16M = 0x1000000L }; -extern int ehca_mr_largepage; - static u32 ehca_encode_hwpage_size(u32 pgsize) { u32 idx = 0; diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index 3dafd7ff36c..43bcf085fcf 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c @@ -88,7 +88,6 @@ int ehca_dealloc_pd(struct ib_pd *pd) u32 cur_pid = current->tgid; struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); int i, leftovers = 0; - extern struct kmem_cache *small_qp_cache; struct ipz_small_queue_page *page, *tmp; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index fdbfebea7d1..24f454162f2 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -758,7 +758,6 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, const u64 logical_address_of_page, const u64 count) { - extern int ehca_debug_level; u64 ret; if (unlikely(ehca_debug_level >= 2)) { diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h index c6937a044e8..a801274ea33 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h @@ -54,6 +54,8 @@ struct ehca_pd; struct ipz_small_queue_page; +extern struct kmem_cache *small_qp_cache; + /* struct generic ehca page */ struct ipz_page { u8 entries[EHCA_PAGESIZE]; diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index b4b786d0dfc..6ad822c3593 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h @@ -100,8 +100,7 @@ struct infinipath_stats { __u64 sps_hwerrs; /* number of times IB link changed state unexpectedly */ __u64 sps_iblink; - /* kernel receive interrupts that didn't read intstat */ - __u64 sps_fastrcvint; + __u64 sps_unused; /* was fastrcvint, no longer implemented */ /* number of kernel (port0) packets received */ __u64 sps_port0pkts; /* number of "ethernet" packets sent by driver */ diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 09c5fd84b1e..6ccba365a24 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -740,7 +740,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, * pioavail updates to memory to stop. */ ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - sendorig & ~IPATH_S_PIOBUFAVAILUPD); + sendorig & ~INFINIPATH_S_PIOBUFAVAILUPD); sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); @@ -1614,7 +1614,7 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd) * it's safer to always do it. * PIOAvail bits are updated by the chip as if normal send had happened. */ -void ipath_cancel_sends(struct ipath_devdata *dd) +void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) { ipath_dbg("Cancelling all in-progress send buffers\n"); dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */ @@ -1627,6 +1627,9 @@ void ipath_cancel_sends(struct ipath_devdata *dd) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_disarm_piobufs(dd, 0, (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k)); + if (restore_sendctrl) /* else done by caller later */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, + dd->ipath_sendctrl); /* and again, be sure all have hit the chip */ ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); @@ -1655,7 +1658,7 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) /* flush all queued sends when going to DOWN or INIT, to be sure that * they don't block MAD packets */ if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 1); ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, dd->ipath_ibcctrl | which); @@ -2000,7 +2003,7 @@ void ipath_shutdown_device(struct ipath_devdata *dd) ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << INFINIPATH_IBCC_LINKINITCMD_SHIFT); - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); /* disable IBC */ dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 9868ccda5f2..5b6ac9a1a70 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c @@ -321,6 +321,8 @@ static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) static int ipath_pe_txe_recover(struct ipath_devdata *); +static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, + u32, unsigned long); /** * ipath_pe_handle_hwerrors - display hardware errors. @@ -555,8 +557,11 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n", dd->ipath_majrev, dd->ipath_minrev); ret = 1; - } else + } else { ret = 0; + if (dd->ipath_minrev >= 2) + dd->ipath_f_put_tid = ipath_pe_put_tid_2; + } return ret; } @@ -1220,7 +1225,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); for (i = 0; i < dd->ipath_rcvtidcnt; i++) - ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, + dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, tidinv); tidbase = (u64 __iomem *) @@ -1229,7 +1234,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) port * dd->ipath_rcvegrcnt * sizeof(*tidbase)); for (i = 0; i < dd->ipath_rcvegrcnt; i++) - ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, + dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, tidinv); } @@ -1395,10 +1400,11 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; dd->ipath_f_clear_tids = ipath_pe_clear_tids; - if (dd->ipath_minrev >= 2) - dd->ipath_f_put_tid = ipath_pe_put_tid_2; - else - dd->ipath_f_put_tid = ipath_pe_put_tid; + /* + * this may get changed after we read the chip revision, + * but we start with the safe version for all revs + */ + dd->ipath_f_put_tid = ipath_pe_put_tid; dd->ipath_f_cleanup = ipath_setup_pe_cleanup; dd->ipath_f_setextled = ipath_setup_pe_setextled; dd->ipath_f_get_base_info = ipath_pe_get_base_info; diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 49951d58380..9dd0bacf846 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -782,7 +782,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) * Follows early_init because some chips have to initialize * PIO buffers in early_init to avoid false parity errors. */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be * done after early_init */ @@ -851,13 +851,14 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, dd->ipath_hwerrmask); - dd->ipath_maskederrs = dd->ipath_ignorederrs; /* clear all */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); /* enable errors that are masked, at least this first time. */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, ~dd->ipath_maskederrs); - /* clear any interrups up to this point (ints still not enabled) */ + dd->ipath_errormask = ipath_read_kreg64(dd, + dd->ipath_kregs->kr_errormask); + /* clear any interrupts up to this point (ints still not enabled) */ ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); /* diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 1fd91c59f24..b29fe7e9b11 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c @@ -303,7 +303,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, * Flush all queued sends when link went to DOWN or INIT, * to be sure that they don't block SMA and other MAD packets */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 1); } else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || lstate == IPATH_IBSTATE_ACTIVE) { @@ -517,10 +517,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint); - /* - * don't report errors that are masked (includes those always - * ignored) - */ + /* don't report errors that are masked */ errs &= ~dd->ipath_maskederrs; /* do these first, they are most important */ @@ -566,19 +563,19 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) * ones on this particular interrupt, which also isn't great */ dd->ipath_maskederrs |= dd->ipath_lasterror | errs; + dd->ipath_errormask &= ~dd->ipath_maskederrs; ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); s_iserr = ipath_decode_err(msg, sizeof msg, - (dd->ipath_maskederrs & ~dd-> - ipath_ignorederrs)); + dd->ipath_maskederrs); - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & + if (dd->ipath_maskederrs & ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS)) ipath_dev_err(dd, "Temporarily disabling " "error(s) %llx reporting; too frequent (%s)\n", - (unsigned long long) (dd->ipath_maskederrs & - ~dd->ipath_ignorederrs), msg); + (unsigned long long)dd->ipath_maskederrs, + msg); else { /* * rcvegrfull and rcvhdrqfull are "normal", @@ -793,19 +790,22 @@ void ipath_clear_freeze(struct ipath_devdata *dd) /* disable error interrupts, to avoid confusion */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); + /* also disable interrupts; errormask is sometimes overwriten */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); + /* * clear all sends, because they have may been * completed by usercode while in freeze mode, and * therefore would not be sent, and eventually * might cause the process to run out of bufs */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); /* ensure pio avail updates continue */ ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - dd->ipath_sendctrl & ~IPATH_S_PIOBUFAVAILUPD); + dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD); ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); @@ -817,7 +817,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd) for (i = 0; i < dd->ipath_pioavregs; i++) { /* deal with 6110 chip bug */ im = i > 3 ? ((i&1) ? i-1 : i+1) : i; - val = ipath_read_kreg64(dd, 0x1000+(im*sizeof(u64))); + val = ipath_read_kreg64(dd, (0x1000/sizeof(u64))+im); dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i] = le64_to_cpu(val); } @@ -832,7 +832,8 @@ void ipath_clear_freeze(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, E_SPKT_ERRS_IGNORE); ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); + ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, -1LL); ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); } @@ -1002,7 +1003,6 @@ irqreturn_t ipath_intr(int irq, void *data) u32 istat, chk0rcv = 0; ipath_err_t estat = 0; irqreturn_t ret; - u32 oldhead, curtail; static unsigned unexpected = 0; static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | (1U<<INFINIPATH_I_RCVURG_SHIFT); @@ -1035,36 +1035,6 @@ irqreturn_t ipath_intr(int irq, void *data) goto bail; } - /* - * We try to avoid reading the interrupt status register, since - * that's a PIO read, and stalls the processor for up to about - * ~0.25 usec. The idea is that if we processed a port0 packet, - * we blindly clear the port 0 receive interrupt bits, and nothing - * else, then return. If other interrupts are pending, the chip - * will re-interrupt us as soon as we write the intclear register. - * We then won't process any more kernel packets (if not the 2nd - * time, then the 3rd or 4th) and we'll then handle the other - * interrupts. We clear the interrupts first so that we don't - * lose intr for later packets that arrive while we are processing. - */ - oldhead = dd->ipath_port0head; - curtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); - if (oldhead != curtail) { - if (dd->ipath_flags & IPATH_GPIO_INTR) { - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, - (u64) (1 << IPATH_GPIO_PORT0_BIT)); - istat = port0rbits | INFINIPATH_I_GPIO; - } - else - istat = port0rbits; - ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); - ipath_kreceive(dd); - if (oldhead != dd->ipath_port0head) { - ipath_stats.sps_fastrcvint++; - goto done; - } - } - istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); if (unlikely(!istat)) { @@ -1225,7 +1195,6 @@ irqreturn_t ipath_intr(int irq, void *data) handle_layer_pioavail(dd); } -done: ret = IRQ_HANDLED; bail: diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index ace63ef78e6..7a7966f7e4f 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -261,18 +261,10 @@ struct ipath_devdata { * limiting of hwerror reporting */ ipath_err_t ipath_lasthwerror; - /* - * errors masked because they occur too fast, also includes errors - * that are always ignored (ipath_ignorederrs) - */ + /* errors masked because they occur too fast */ ipath_err_t ipath_maskederrs; /* time in jiffies at which to re-enable maskederrs */ unsigned long ipath_unmasktime; - /* - * errors always ignored (masked), at least for a given - * chip/device, because they are wrong or not useful - */ - ipath_err_t ipath_ignorederrs; /* count of egrfull errors, combined for all ports */ u64 ipath_last_tidfull; /* for ipath_qcheck() */ @@ -436,6 +428,7 @@ struct ipath_devdata { u64 ipath_lastibcstat; /* hwerrmask shadow */ ipath_err_t ipath_hwerrmask; + ipath_err_t ipath_errormask; /* errormask shadow */ /* interrupt config reg shadow */ u64 ipath_intconfig; /* kr_sendpiobufbase value */ @@ -683,7 +676,7 @@ int ipath_unordered_wc(void); void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, unsigned cnt); -void ipath_cancel_sends(struct ipath_devdata *); +void ipath_cancel_sends(struct ipath_devdata *, int); int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 73ed17d0318..bae4f56f727 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c @@ -196,6 +196,45 @@ static void ipath_qcheck(struct ipath_devdata *dd) } } +static void ipath_chk_errormask(struct ipath_devdata *dd) +{ + static u32 fixed; + u32 ctrl; + unsigned long errormask; + unsigned long hwerrs; + + if (!dd->ipath_errormask || !(dd->ipath_flags & IPATH_INITTED)) + return; + + errormask = ipath_read_kreg64(dd, dd->ipath_kregs->kr_errormask); + + if (errormask == dd->ipath_errormask) + return; + fixed++; + + hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); + ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); + + ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, + dd->ipath_errormask); + + if ((hwerrs & dd->ipath_hwerrmask) || + (ctrl & INFINIPATH_C_FREEZEMODE)) { + /* force re-interrupt of pending events, just in case */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, 0ULL); + ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, 0ULL); + ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); + dev_info(&dd->pcidev->dev, + "errormask fixed(%u) %lx -> %lx, ctrl %x hwerr %lx\n", + fixed, errormask, (unsigned long)dd->ipath_errormask, + ctrl, hwerrs); + } else + ipath_dbg("errormask fixed(%u) %lx -> %lx, no freeze\n", + fixed, errormask, + (unsigned long)dd->ipath_errormask); +} + + /** * ipath_get_faststats - get word counters from chip before they overflow * @opaque - contains a pointer to the infinipath device ipath_devdata @@ -251,14 +290,13 @@ void ipath_get_faststats(unsigned long opaque) dd->ipath_lasterror = 0; if (dd->ipath_lasthwerror) dd->ipath_lasthwerror = 0; - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) + if (dd->ipath_maskederrs && time_after(jiffies, dd->ipath_unmasktime)) { char ebuf[256]; int iserr; iserr = ipath_decode_err(ebuf, sizeof ebuf, - (dd->ipath_maskederrs & ~dd-> - ipath_ignorederrs)); - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & + dd->ipath_maskederrs); + if (dd->ipath_maskederrs & ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS )) ipath_dev_err(dd, "Re-enabling masked errors " @@ -278,9 +316,12 @@ void ipath_get_faststats(unsigned long opaque) ipath_cdbg(ERRPKT, "Re-enabling packet" " problem interrupt (%s)\n", ebuf); } - dd->ipath_maskederrs = dd->ipath_ignorederrs; + + /* re-enable masked errors */ + dd->ipath_errormask |= dd->ipath_maskederrs; ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); + dd->ipath_maskederrs = 0; } /* limit qfull messages to ~one per minute per port */ @@ -294,6 +335,7 @@ void ipath_get_faststats(unsigned long opaque) } } + ipath_chk_errormask(dd); done: mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); } diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f6315dfb213..ba0428d872a 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1209,7 +1209,6 @@ static void set_datagram_seg(struct mlx4_wqe_datagram_seg *dseg, memcpy(dseg->av, &to_mah(wr->wr.ud.ah)->av, sizeof (struct mlx4_av)); dseg->dqpn = cpu_to_be32(wr->wr.ud.remote_qpn); dseg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey); - } static void set_data_seg(struct mlx4_wqe_data_seg *dseg, diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 7195c946152..b1a9c4cdec9 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -29,8 +29,6 @@ struct af9005_fe_state { struct dvb_usb_device *d; - struct dvb_frontend *tuner; - fe_status_t stat; /* retraining parameters */ @@ -345,8 +343,8 @@ static int af9005_reset_pre_viterbi(struct dvb_frontend *fe) 1 & 0xff); if (ret) return ret; - af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, - 1 >> 8); + ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, + 1 >> 8); if (ret) return ret; /* reset pre viterbi error count */ @@ -447,7 +445,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) u8 temp; int ret; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; *stat = 0; @@ -493,7 +491,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) { struct af9005_fe_state *state = fe->demodulator_priv; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; af9005_fe_refresh_state(fe); *ber = state->ber; @@ -503,7 +501,7 @@ static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) { struct af9005_fe_state *state = fe->demodulator_priv; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; af9005_fe_refresh_state(fe); *unc = state->unc; @@ -517,7 +515,7 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, int ret; u8 if_gain, rf_gain; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; ret = af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, @@ -881,10 +879,8 @@ static int af9005_fe_init(struct dvb_frontend *fe) af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, reg_ofdm_rst_pos, reg_ofdm_rst_len, 1))) return ret; - if ((ret = - af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, - reg_ofdm_rst_pos, reg_ofdm_rst_len, 0))) - return ret; + ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, + reg_ofdm_rst_pos, reg_ofdm_rst_len, 0); if (ret) return ret; @@ -1041,7 +1037,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) return ret; /* attach tuner and init */ - if (state->tuner == NULL) { + if (fe->ops.tuner_ops.release == NULL) { /* read tuner and board id from eeprom */ ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); if (ret) { @@ -1058,20 +1054,16 @@ static int af9005_fe_init(struct dvb_frontend *fe) return ret; } if1 = (u16) (buf[0] << 8) + buf[1]; - state->tuner = - dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, - &af9005_mt2060_config, if1); - if (state->tuner == NULL) { + if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, + &af9005_mt2060_config, if1) == NULL) { deb_info("MT2060 attach failed\n"); return -ENODEV; } break; case 3: /* QT1010 */ case 9: /* QT1010B */ - state->tuner = - dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, - &af9005_qt1010_config); - if (state->tuner == NULL) { + if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, + &af9005_qt1010_config) ==NULL) { deb_info("QT1010 attach failed\n"); return -ENODEV; } @@ -1080,7 +1072,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) err("Unsupported tuner type %d", buf[0]); return -ENODEV; } - ret = state->tuner->ops.tuner_ops.init(state->tuner); + ret = fe->ops.tuner_ops.init(fe); if (ret) return ret; } @@ -1118,7 +1110,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, fep->u.ofdm.bandwidth); - if (state->tuner == NULL) { + if (fe->ops.tuner_ops.release == NULL) { err("Tuner not attached"); return -ENODEV; } @@ -1199,7 +1191,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return ret; /* set tuner */ deb_info("set tuner\n"); - ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep); + ret = fe->ops.tuner_ops.set_params(fe, fep); if (ret) return ret; @@ -1435,12 +1427,6 @@ static void af9005_fe_release(struct dvb_frontend *fe) { struct af9005_fe_state *state = (struct af9005_fe_state *)fe->demodulator_priv; - if (state->tuner != NULL && state->tuner->ops.tuner_ops.release != NULL) { - state->tuner->ops.tuner_ops.release(state->tuner); -#ifdef CONFIG_DVB_CORE_ATTACH - symbol_put_addr(state->tuner->ops.tuner_ops.release); -#endif - } kfree(state); } @@ -1458,7 +1444,6 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) deb_info("attaching frontend af9005\n"); state->d = d; - state->tuner = NULL; state->opened = 0; memcpy(&state->frontend.ops, &af9005_fe_ops, diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 0c0b94767bc..ca99e439c97 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -501,7 +501,7 @@ static struct dvb_pll_desc dvb_pll_opera1 = { /* Philips FCV1236D */ -struct dvb_pll_desc dvb_pll_fcv1236d = { +static struct dvb_pll_desc dvb_pll_fcv1236d = { /* Bit_0: RF Input select * Bit_1: 0=digital, 1=analog */ diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 387cb2122d4..f6715007d40 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -33,6 +33,7 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/firmware.h> +#include <net/checksum.h> #include <asm/io.h> @@ -45,7 +46,7 @@ static void boot_msp34xx(struct bttv *btv, int pin); static void boot_bt832(struct bttv *btv); static void hauppauge_eeprom(struct bttv *btv); static void avermedia_eeprom(struct bttv *btv); -static void osprey_eeprom(struct bttv *btv); +static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); static void modtec_eeprom(struct bttv *btv); static void init_PXC200(struct bttv *btv); static void init_RTV24(struct bttv *btv); @@ -2843,13 +2844,28 @@ struct tvcard bttv_tvcards[] = { .has_remote = 1, }, /* ---- card 0x8c ---------------------------------- */ + /* Has four Bt878 chips behind a PCI bridge, each chip has: + one external BNC composite input (mux 2) + three internal composite inputs (unknown muxes) + an 18-bit stereo A/D (CS5331A), which has: + one external stereo unblanced (RCA) audio connection + one (or 3?) internal stereo balanced (XLR) audio connection + input is selected via gpio to a 14052B mux + (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300) + gain is controlled via an X9221A chip on the I2C bus @0x28 + sample rate is controlled via gpio to an MK1413S + (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3) + There is neither a tuner nor an svideo input. */ [BTTV_BOARD_OSPREY440] = { .name = "Osprey 440", - .video_inputs = 1, - .audio_inputs = 1, + .video_inputs = 4, + .audio_inputs = 2, /* this is meaningless */ .tuner = UNSET, - .svhs = 1, - .muxsel = { 2 }, + .svhs = UNSET, + .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ + .gpiomask = 0x303, + .gpiomute = 0x000, /* int + 32kHz */ + .gpiomux = { 0, 0, 0x000, 0x100}, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -3453,11 +3469,12 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_BOARD_OSPREY2xx: case BTTV_BOARD_OSPREY2x0_SVID: case BTTV_BOARD_OSPREY2x0: + case BTTV_BOARD_OSPREY440: case BTTV_BOARD_OSPREY500: case BTTV_BOARD_OSPREY540: case BTTV_BOARD_OSPREY2000: bttv_readee(btv,eeprom_data,0xa0); - osprey_eeprom(btv); + osprey_eeprom(btv, eeprom_data); break; case BTTV_BOARD_IDS_EAGLE: init_ids_eagle(btv); @@ -3748,106 +3765,119 @@ static int __devinit pvr_boot(struct bttv *btv) /* ----------------------------------------------------------------------- */ /* some osprey specific stuff */ -static void __devinit osprey_eeprom(struct bttv *btv) +static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) { - int i = 0; - unsigned char *ee = eeprom_data; - unsigned long serial = 0; - - if (btv->c.type == 0) { - /* this might be an antique... check for MMAC label in eeprom */ - if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { - unsigned char checksum = 0; - for (i = 0; i < 21; i++) - checksum += ee[i]; - if (checksum != ee[21]) - return; - btv->c.type = BTTV_BOARD_OSPREY1x0_848; - for (i = 12; i < 21; i++) - serial *= 10, serial += ee[i] - '0'; - } + int i; + u32 serial = 0; + int cardid = -1; + + /* This code will nevery actually get called in this case.... */ + if (btv->c.type == BTTV_BOARD_UNKNOWN) { + /* this might be an antique... check for MMAC label in eeprom */ + if (!strncmp(ee, "MMAC", 4)) { + u8 checksum = 0; + for (i = 0; i < 21; i++) + checksum += ee[i]; + if (checksum != ee[21]) + return; + cardid = BTTV_BOARD_OSPREY1x0_848; + for (i = 12; i < 21; i++) + serial *= 10, serial += ee[i] - '0'; + } } else { - unsigned short type; - int offset = 4*16; - - for (; offset < 8*16; offset += 16) { - unsigned short checksum = 0; - /* verify the checksum */ - for (i = 0; i < 14; i++) - checksum += ee[i+offset]; - checksum = ~checksum; /* no idea why */ - if ((((checksum>>8)&0x0FF) == ee[offset+14]) && - ((checksum & 0x0FF) == ee[offset+15])) { - break; - } - } - - if (offset >= 8*16) - return; - - /* found a valid descriptor */ - type = (ee[offset+4]<<8) | (ee[offset+5]); - - switch(type) { - /* 848 based */ - case 0x0004: - btv->c.type = BTTV_BOARD_OSPREY1x0_848; - break; - case 0x0005: - btv->c.type = BTTV_BOARD_OSPREY101_848; - break; - - /* 878 based */ - case 0x0012: - case 0x0013: - btv->c.type = BTTV_BOARD_OSPREY1x0; - break; - case 0x0014: - case 0x0015: - btv->c.type = BTTV_BOARD_OSPREY1x1; - break; - case 0x0016: - case 0x0017: - case 0x0020: - btv->c.type = BTTV_BOARD_OSPREY1x1_SVID; - break; - case 0x0018: - case 0x0019: - case 0x001E: - case 0x001F: - btv->c.type = BTTV_BOARD_OSPREY2xx; - break; - case 0x001A: - case 0x001B: - btv->c.type = BTTV_BOARD_OSPREY2x0_SVID; - break; - case 0x0040: - btv->c.type = BTTV_BOARD_OSPREY500; - break; - case 0x0050: - case 0x0056: - btv->c.type = BTTV_BOARD_OSPREY540; - /* bttv_osprey_540_init(btv); */ - break; - case 0x0060: - case 0x0070: - case 0x00A0: - btv->c.type = BTTV_BOARD_OSPREY2x0; - /* enable output on select control lines */ - gpio_inout(0xffffff,0x000303); - break; - default: - /* unknown...leave generic, but get serial # */ - break; - } - serial = (ee[offset+6] << 24) - | (ee[offset+7] << 16) - | (ee[offset+8] << 8) - | (ee[offset+9]); - } - - printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n", - btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial); + unsigned short type; + + for (i = 4*16; i < 8*16; i += 16) { + u16 checksum = ip_compute_csum(ee + i, 16); + + if ((checksum&0xff) + (checksum>>8) == 0xff) + break; + } + if (i >= 8*16) + return; + ee += i; + + /* found a valid descriptor */ + type = be16_to_cpup((u16*)(ee+4)); + + switch(type) { + /* 848 based */ + case 0x0004: + cardid = BTTV_BOARD_OSPREY1x0_848; + break; + case 0x0005: + cardid = BTTV_BOARD_OSPREY101_848; + break; + + /* 878 based */ + case 0x0012: + case 0x0013: + cardid = BTTV_BOARD_OSPREY1x0; + break; + case 0x0014: + case 0x0015: + cardid = BTTV_BOARD_OSPREY1x1; + break; + case 0x0016: + case 0x0017: + case 0x0020: + cardid = BTTV_BOARD_OSPREY1x1_SVID; + break; + case 0x0018: + case 0x0019: + case 0x001E: + case 0x001F: + cardid = BTTV_BOARD_OSPREY2xx; + break; + case 0x001A: + case 0x001B: + cardid = BTTV_BOARD_OSPREY2x0_SVID; + break; + case 0x0040: + cardid = BTTV_BOARD_OSPREY500; + break; + case 0x0050: + case 0x0056: + cardid = BTTV_BOARD_OSPREY540; + /* bttv_osprey_540_init(btv); */ + break; + case 0x0060: + case 0x0070: + case 0x00A0: + cardid = BTTV_BOARD_OSPREY2x0; + /* enable output on select control lines */ + gpio_inout(0xffffff,0x000303); + break; + case 0x00D8: + cardid = BTTV_BOARD_OSPREY440; + break; + default: + /* unknown...leave generic, but get serial # */ + printk(KERN_INFO "bttv%d: " + "osprey eeprom: unknown card type 0x%04x\n", + btv->c.nr, type); + break; + } + serial = be32_to_cpup((u32*)(ee+6)); + } + + printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", + btv->c.nr, cardid, + cardid>0 ? bttv_tvcards[cardid].name : "Unknown", serial); + + if (cardid<0 || btv->c.type == cardid) + return; + + /* card type isn't set correctly */ + if (card[btv->c.nr] < bttv_num_tvcards) { + printk(KERN_WARNING "bttv%d: osprey eeprom: " + "Not overriding user specified card type\n", btv->c.nr); + } else { + printk(KERN_INFO "bttv%d: osprey eeprom: " + "Changing card type from %d to %d\n", btv->c.nr, + btv->c.type, cardid); + btv->c.type = cardid; + } } /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 91b588d261a..8abb34a3581 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -417,6 +417,7 @@ struct ivtv_mailbox_data { #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ #define IVTV_F_I_PIO 19 /* PIO in progress */ +#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ /* Event notifications */ #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 8e97a938398..5dd519caf81 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -757,6 +757,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) itv->output_mode = OUT_NONE; itv->speed = 0; + clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); ivtv_release_stream(s); } @@ -799,7 +800,16 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) ivtv_unmute(itv); ivtv_release_stream(s); } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { + struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; + ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); + + /* If all output streams are closed, and if the user doesn't have + IVTV_DEC_STREAM_TYPE_VOUT open, then disable VBI on TV-out. */ + if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { + /* disable VBI on TV-out */ + ivtv_disable_vbi(itv); + } } else { ivtv_stop_capture(id, 0); } diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index d0feabf9308..425eb106390 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c @@ -72,8 +72,8 @@ retry: dst++; src++; } - release_firmware(fw); IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); + release_firmware(fw); return size; } IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 4773453e8da..047624b9e27 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -285,6 +285,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) return -EBUSY; + if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { + /* forces ivtv_set_speed to be called */ + itv->speed = 0; + } return ivtv_start_decoding(id, vc->play.speed); } @@ -309,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (atomic_read(&itv->decoding) > 0) { ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); + set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); } break; @@ -317,8 +322,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (try) break; if (itv->output_mode != OUT_MPG) return -EBUSY; - if (atomic_read(&itv->decoding) > 0) { - ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0); + if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { + int speed = itv->speed; + itv->speed = 0; + return ivtv_start_decoding(id, speed); } break; diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 814a673712b..5e3b679202a 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c @@ -40,6 +40,7 @@ #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ +#define API_NO_POLL (1 << 6) /* Avoid pointless polling */ struct ivtv_api_info { int flags; /* Flags, see above */ @@ -51,7 +52,7 @@ struct ivtv_api_info { static const struct ivtv_api_info api_info[256] = { /* MPEG encoder API */ API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT), + API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), @@ -96,7 +97,7 @@ static const struct ivtv_api_info api_info[256] = { /* MPEG decoder API */ API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT), + API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), @@ -290,6 +291,13 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) /* Get results */ then = jiffies; + if (!(flags & API_NO_POLL)) { + /* First try to poll, then switch to delays */ + for (i = 0; i < 100; i++) { + if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE) + break; + } + } while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { if (jiffies - then > api_timeout) { IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); @@ -301,7 +309,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) if (flags & API_NO_WAIT_RES) mdelay(1); else - ivtv_msleep_timeout(10, 0); + ivtv_msleep_timeout(1, 0); } if (jiffies - then > msecs_to_jiffies(100)) IVTV_DEBUG_WARN("%s took %u jiffies\n", diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 322b347b67c..51df3f85503 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -603,10 +603,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); - /* disable VBI signals, if the MPEG stream contains VBI data, - then that data will be processed automatically for you. */ - ivtv_disable_vbi(itv); - /* set audio mode to left/stereo for dual/stereo mode. */ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); @@ -639,7 +635,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) } if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, itv->params.width, itv->params.height, itv->params.audio_properties)) { - IVTV_DEBUG_WARN("COULDN'T INITIALIZE DECODER SOURCE\n"); + IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } return 0; } @@ -909,11 +905,6 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) clear_bit(IVTV_F_S_STREAMING, &s->s_flags); ivtv_flush_queues(s); - if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { - /* disable VBI on TV-out */ - ivtv_disable_vbi(itv); - } - /* decrement decoding */ atomic_dec(&itv->decoding); diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 868b6886fe7..e3371f97224 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -517,6 +517,7 @@ static int vidioc_g_register (struct file *file, void *priv, __FUNCTION__, errCode); return errCode; } + reg->val = errCode; return 0; } @@ -531,8 +532,8 @@ static int vidioc_s_register (struct file *file, void *priv, if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) return -EINVAL; /* NT100x has a 8-bit register space */ - reg->val = (u8)usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); - if (reg->val < 0) { + errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); + if (errCode < 0) { err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode); return errCode; diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 8fb4a3414e0..937c4a616c0 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h @@ -240,11 +240,16 @@ enum gpcs_type { struct zoran_format { char *name; +#ifdef CONFIG_VIDEO_V4L1_COMPAT int palette; +#endif +#ifdef CONFIG_VIDEO_V4L2 __u32 fourcc; int colorspace; +#endif int depth; __u32 flags; + __u32 vfespfr; }; /* flags */ #define ZORAN_FORMAT_COMPRESSED 1<<0 diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index b0752767ee4..ba2f4ed2948 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -429,8 +429,6 @@ 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 && 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 * we get the correct colors when uncompressing to the screen */ @@ -439,36 +437,6 @@ zr36057_set_vfe (struct zoran *zr, if (zr->norm != VIDEO_MODE_NTSC) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; - switch (format->palette) { - - case VIDEO_PALETTE_YUYV: - case VIDEO_PALETTE_YUV422: - reg |= ZR36057_VFESPFR_YUV422; - break; - - case VIDEO_PALETTE_RGB555: - reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif; - break; - - case VIDEO_PALETTE_RGB565: - reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif; - break; - - case VIDEO_PALETTE_RGB24: - reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24; - break; - - case VIDEO_PALETTE_RGB32: - reg |= ZR36057_VFESPFR_RGB888; - break; - - default: - dprintk(1, - KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n", - ZR_DEVNAME(zr), format->palette); - return; - - } if (HorDcm >= 48) { reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ } else if (HorDcm >= 32) { @@ -476,6 +444,7 @@ zr36057_set_vfe (struct zoran *zr, } else if (HorDcm >= 16) { reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ } + reg |= format->vfespfr; btwrite(reg, ZR36057_VFESPFR); /* display configuration */ @@ -651,11 +620,17 @@ zr36057_set_memgrab (struct zoran *zr, int mode) { if (mode) { - if (btread(ZR36057_VSSFGR) & - (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab)) + /* We only check SnapShot and not FrameGrab here. SnapShot==1 + * means a capture is already in progress, but FrameGrab==1 + * doesn't necessary mean that. It's more correct to say a 1 + * to 0 transition indicates a capture completed. If a + * capture is pending when capturing is tuned off, FrameGrab + * will be stuck at 1 until capturing is turned back on. + */ + if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) dprintk(1, KERN_WARNING - "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n", + "%s: zr36057_set_memgrab(1) with SnapShot on!?\n", ZR_DEVNAME(zr)); /* switch on VSync interrupts */ @@ -672,11 +647,12 @@ zr36057_set_memgrab (struct zoran *zr, zr->v4l_memgrab_active = 1; } else { - zr->v4l_memgrab_active = 0; - /* switch off VSync interrupts */ btand(~zr->card.vsync_int, ZR36057_ICR); // SW + zr->v4l_memgrab_active = 0; + zr->v4l_grab_frame = NO_GRAB_ACTIVE; + /* reenable grabbing to screen if it was running */ if (zr->v4l_overlay_active) { zr36057_overlay(zr, 1); diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 17118a490f8..72a037b75d6 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -99,88 +99,103 @@ #include <asm/byteorder.h> -const struct zoran_format zoran_formats[] = { - { - .name = "15-bit RGB", - .palette = VIDEO_PALETTE_RGB555, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_RGB555, +#if defined(CONFIG_VIDEO_V4L2) && defined(CONFIG_VIDEO_V4L1_COMPAT) +#define ZFMT(pal, fcc, cs) \ + .palette = (pal), .fourcc = (fcc), .colorspace = (cs) +#elif defined(CONFIG_VIDEO_V4L2) +#define ZFMT(pal, fcc, cs) \ + .fourcc = (fcc), .colorspace = (cs) #else - .fourcc = V4L2_PIX_FMT_RGB555X, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, +#define ZFMT(pal, fcc, cs) \ + .palette = (pal) #endif + +const struct zoran_format zoran_formats[] = { + { + .name = "15-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB555, + V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif| + ZR36057_VFESPFR_LittleEndian, }, { - .name = "16-bit RGB", - .palette = VIDEO_PALETTE_RGB565, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_RGB565, -#else - .fourcc = V4L2_PIX_FMT_RGB565X, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + .name = "15-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), + .depth = 15, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, + }, { + .name = "16-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB565, + V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif| + ZR36057_VFESPFR_LittleEndian, + }, { + .name = "16-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), + .depth = 16, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - .palette = VIDEO_PALETTE_RGB24, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_BGR24, -#else - .fourcc = V4L2_PIX_FMT_RGB24, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + ZFMT(VIDEO_PALETTE_RGB24, + V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { - .name = "32-bit RGB", - .palette = VIDEO_PALETTE_RGB32, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_BGR32, -#else - .fourcc = V4L2_PIX_FMT_RGB32, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + .name = "32-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB32, + V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), + .depth = 32, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, + }, { + .name = "32-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - .palette = VIDEO_PALETTE_YUV422, -#ifdef CONFIG_VIDEO_V4L2 - .fourcc = V4L2_PIX_FMT_YUYV, - .colorspace = V4L2_COLORSPACE_SMPTE170M, -#endif + ZFMT(VIDEO_PALETTE_YUV422, + V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), + .depth = 16, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_YUV422, + }, { + .name = "4:2:2, packed, UYVY", + ZFMT(VIDEO_PALETTE_UYVY, + V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - .palette = -1, -#ifdef CONFIG_VIDEO_V4L2 - .fourcc = V4L2_PIX_FMT_MJPEG, - .colorspace = V4L2_COLORSPACE_SMPTE170M, -#endif + ZFMT(-1, + V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | ZORAN_FORMAT_COMPRESSED, } }; -static const int zoran_num_formats = - (sizeof(zoran_formats) / sizeof(struct zoran_format)); +#define NUM_FORMATS ARRAY_SIZE(zoran_formats) // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined @@ -768,13 +783,13 @@ v4l_grab (struct file *file, struct zoran *zr = fh->zr; int res = 0, i; - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { if (zoran_formats[i].palette == mp->format && zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) break; } - if (i == zoran_num_formats || zoran_formats[i].depth == 0) { + if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { dprintk(1, KERN_ERR "%s: v4l_grab() - wrong bytes-per-pixel format\n", @@ -1173,10 +1188,14 @@ zoran_close_end_session (struct file *file) /* v4l capture */ if (fh->v4l_buffers.active != ZORAN_FREE) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); zr->v4l_buffers.allocated = 0; zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); } /* v4l buffers */ @@ -2107,7 +2126,7 @@ zoran_do_ioctl (struct inode *inode, vpict->colour, vpict->contrast, vpict->depth, vpict->palette); - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { const struct zoran_format *fmt = &zoran_formats[i]; if (fmt->palette != -1 && @@ -2116,7 +2135,7 @@ zoran_do_ioctl (struct inode *inode, fmt->depth == vpict->depth) break; } - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOCSPICT - Invalid palette %d\n", @@ -2220,10 +2239,10 @@ zoran_do_ioctl (struct inode *inode, ZR_DEVNAME(zr), vbuf->base, vbuf->width, vbuf->height, vbuf->depth, vbuf->bytesperline); - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].depth == vbuf->depth) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", @@ -2672,14 +2691,14 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { if (zoran_formats[i].flags & flag) num++; if (num == fmt->index) break; } if (fmt->index < 0 /* late, but not too late */ || - i == zoran_num_formats) + i == NUM_FORMATS) return -EINVAL; memset(fmt, 0, sizeof(*fmt)); @@ -2737,7 +2756,8 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.pix.height = fh->v4l_settings.height; fmt->fmt.pix.sizeimage = - fh->v4l_buffers.buffer_size; + fh->v4l_settings.bytesperline * + fh->v4l_settings.height; fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; fmt->fmt.pix.colorspace = @@ -2941,11 +2961,11 @@ zoran_do_ioctl (struct inode *inode, sfmtjpg_unlock_and_return: mutex_unlock(&zr->resource_lock); } else { - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", @@ -2984,8 +3004,9 @@ zoran_do_ioctl (struct inode *inode, /* tell the user the * results/missing stuff */ - fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size /*zr->gbpl * zr->gheight */ - ; + fmt->fmt.pix.sizeimage = + fh->v4l_settings.height * + fh->v4l_settings.bytesperline; if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) fmt->fmt.pix.field = @@ -3053,10 +3074,10 @@ zoran_do_ioctl (struct inode *inode, fb->fmt.bytesperline, fb->fmt.pixelformat, (char *) &printformat); - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].fourcc == fb->fmt.pixelformat) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", @@ -3439,8 +3460,13 @@ zoran_do_ioctl (struct inode *inode, goto strmoff_unlock_and_return; /* unload capture */ - if (zr->v4l_memgrab_active) + if (zr->v4l_memgrab_active) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); + } for (i = 0; i < fh->v4l_buffers.num_buffers; i++) zr->v4l_buffers.buffer[i].state = @@ -3704,11 +3730,11 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", ZR_DEVNAME(zr), (unsigned long long)*std); - if (*std == V4L2_STD_PAL) + if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) norm = VIDEO_MODE_PAL; - else if (*std == V4L2_STD_NTSC) + else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) norm = VIDEO_MODE_NTSC; - else if (*std == V4L2_STD_SECAM) + else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) norm = VIDEO_MODE_SECAM; else if (*std == V4L2_STD_ALL) norm = VIDEO_MODE_AUTO; @@ -4149,11 +4175,11 @@ zoran_do_ioctl (struct inode *inode, V4L2_BUF_TYPE_VIDEO_CAPTURE) { int i; - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { res = -EINVAL; goto tryfmt_unlock_and_return; } @@ -4213,8 +4239,8 @@ zoran_poll (struct file *file, { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - wait_queue_head_t *queue = NULL; int res = 0, frame; + unsigned long flags; /* we should check whether buffers are ready to be synced on * (w/o waits - O_NONBLOCK) here @@ -4228,51 +4254,58 @@ zoran_poll (struct file *file, switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: - if (fh->v4l_buffers.active == ZORAN_FREE || - zr->v4l_pend_head == zr->v4l_pend_tail) { - dprintk(1, - "%s: zoran_poll() - no buffers queued\n", - ZR_DEVNAME(zr)); - res = POLLNVAL; - goto poll_unlock_and_return; - } - queue = &zr->v4l_capq; - frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; - poll_wait(file, queue, wait); - if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) + poll_wait(file, &zr->v4l_capq, wait); + frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + + spin_lock_irqsave(&zr->spinlock, flags); + dprintk(3, + KERN_DEBUG + "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", + ZR_DEVNAME(zr), __FUNCTION__, + "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, + "UPMD"[zr->v4l_buffers.buffer[frame].state], + zr->v4l_pend_tail, zr->v4l_pend_head); + /* Process is the one capturing? */ + if (fh->v4l_buffers.active != ZORAN_FREE && + /* Buffer ready to DQBUF? */ + zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) res = POLLIN | POLLRDNORM; + spin_unlock_irqrestore(&zr->spinlock, flags); + break; case ZORAN_MAP_MODE_JPG_REC: case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->jpg_buffers.active == ZORAN_FREE || - zr->jpg_que_head == zr->jpg_que_tail) { - dprintk(1, - "%s: zoran_poll() - no buffers queued\n", - ZR_DEVNAME(zr)); - res = POLLNVAL; - goto poll_unlock_and_return; - } - queue = &zr->jpg_capq; + poll_wait(file, &zr->jpg_capq, wait); frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - poll_wait(file, queue, wait); - if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { + + spin_lock_irqsave(&zr->spinlock, flags); + dprintk(3, + KERN_DEBUG + "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", + ZR_DEVNAME(zr), __FUNCTION__, + "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, + "UPMD"[zr->jpg_buffers.buffer[frame].state], + zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); + if (fh->jpg_buffers.active != ZORAN_FREE && + zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) res = POLLIN | POLLRDNORM; else res = POLLOUT | POLLWRNORM; } + spin_unlock_irqrestore(&zr->spinlock, flags); + break; default: dprintk(1, + KERN_ERR "%s: zoran_poll() - internal error, unknown map_mode=%d\n", ZR_DEVNAME(zr), fh->map_mode); res = POLLNVAL; - goto poll_unlock_and_return; } -poll_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; @@ -4368,11 +4401,15 @@ zoran_vm_close (struct vm_area_struct *vma) mutex_lock(&zr->resource_lock); if (fh->v4l_buffers.active != ZORAN_FREE) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); zr->v4l_buffers.allocated = 0; zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); } //v4l_fbuffer_free(file); fh->v4l_buffers.allocated = 0; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 661c747389e..51e1cb47273 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -178,6 +178,7 @@ #define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */ #define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */ #define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */ +#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */ enum { NvRegIrqStatus = 0x000, @@ -5172,7 +5173,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* check the workaround bit for correct mac address order */ txreg = readl(base + NvRegTransmitPoll); - if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) { + if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) || + (id->driver_data & DEV_HAS_CORRECT_MACADDR)) { /* mac address is already in correct order */ dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff; dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff; @@ -5500,67 +5502,67 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, {0,}, }; diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index ac3596f45dd..100bf410bf5 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -245,7 +245,7 @@ int __init gfar_mdio_init(void) return driver_register(&gianfar_mdio_driver); } -void __exit gfar_mdio_exit(void) +void gfar_mdio_exit(void) { driver_unregister(&gianfar_mdio_driver); } diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 5d340046951..b373091c703 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h @@ -42,5 +42,5 @@ struct gfar_mii { int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum); int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int __init gfar_mdio_init(void); -void __exit gfar_mdio_exit(void); +void gfar_mdio_exit(void); #endif /* GIANFAR_PHY_H */ diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 721ee38d224..c429a5002dd 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -143,6 +143,52 @@ static void __NS8390_init(struct net_device *dev, int startp); * annoying the transmit function is called bh atomic. That places * restrictions on the user context callers as disable_irq won't save * them. + * + * Additional explanation of problems with locking by Alan Cox: + * + * "The author (me) didn't use spin_lock_irqsave because the slowness of the + * card means that approach caused horrible problems like losing serial data + * at 38400 baud on some chips. Rememeber many 8390 nics on PCI were ISA + * chips with FPGA front ends. + * + * Ok the logic behind the 8390 is very simple: + * + * Things to know + * - IRQ delivery is asynchronous to the PCI bus + * - Blocking the local CPU IRQ via spin locks was too slow + * - The chip has register windows needing locking work + * + * So the path was once (I say once as people appear to have changed it + * in the mean time and it now looks rather bogus if the changes to use + * disable_irq_nosync_irqsave are disabling the local IRQ) + * + * + * Take the page lock + * Mask the IRQ on chip + * Disable the IRQ (but not mask locally- someone seems to have + * broken this with the lock validator stuff) + * [This must be _nosync as the page lock may otherwise + * deadlock us] + * Drop the page lock and turn IRQs back on + * + * At this point an existing IRQ may still be running but we can't + * get a new one + * + * Take the lock (so we know the IRQ has terminated) but don't mask + * the IRQs on the processor + * Set irqlock [for debug] + * + * Transmit (slow as ****) + * + * re-enable the IRQ + * + * + * We have to use disable_irq because otherwise you will get delayed + * interrupts on the APIC bus deadlocking the transmit path. + * + * Quite hairy but the chip simply wasn't designed for SMP and you can't + * even ACK an interrupt without risking corrupting other parallel + * activities on the chip." [lkml, 25 Jul 2007] */ diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index d0808fa3ec8..5b87183e62c 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -255,10 +255,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, int err; index = mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap); - if (index == -1) { - err = -ENOMEM; - goto err; - } + if (index == -1) + return -ENOMEM; mr->iova = iova; mr->size = size; @@ -269,15 +267,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); if (err) - goto err_index; - - return 0; - -err_index: - mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index); + mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index); -err: - kfree(mr); return err; } EXPORT_SYMBOL_GPL(mlx4_mr_alloc); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 19e2fa940ac..08a62acde8b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -335,7 +335,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.pdev = pdev; adapter->ahw.pci_func = pci_func_id; spin_lock_init(&adapter->tx_lock); - spin_lock_init(&adapter->lock); /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ @@ -895,8 +894,6 @@ static int netxen_nic_open(struct net_device *netdev) /* Done here again so that even if phantom sw overwrote it, * we set it */ - if (adapter->macaddr_set) - adapter->macaddr_set(adapter, netdev->dev_addr); if (adapter->init_port && adapter->init_port(adapter, adapter->portnum) != 0) { del_timer_sync(&adapter->watchdog_timer); @@ -904,6 +901,8 @@ static int netxen_nic_open(struct net_device *netdev) netxen_nic_driver_name, adapter->portnum); return -EIO; } + if (adapter->macaddr_set) + adapter->macaddr_set(adapter, netdev->dev_addr); netxen_nic_set_link_parameters(adapter); @@ -930,6 +929,8 @@ static int netxen_nic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_stop_queue(netdev); + netxen_nic_disable_int(adapter); + cmd_buff = adapter->cmd_buf_arr; for (i = 0; i < adapter->max_tx_desc_count; i++) { buffrag = cmd_buff->frag_array; @@ -1226,15 +1227,12 @@ static void netxen_tx_timeout_task(struct work_struct *work) { struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, tx_timeout_task); - unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, adapter->netdev->name); - spin_lock_irqsave(&adapter->lock, flags); netxen_nic_close(adapter->netdev); netxen_nic_open(adapter->netdev); - spin_unlock_irqrestore(&adapter->lock, flags); adapter->netdev->trans_start = jiffies; netif_wake_queue(adapter->netdev); } @@ -1243,28 +1241,12 @@ static int netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) { u32 ret = 0; - u32 our_int = 0; DPRINTK(INFO, "Entered handle ISR\n"); adapter->stats.ints++; - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - /* not our interrupt */ - if ((our_int & (0x80 << adapter->portnum)) == 0) - return ret; - } - netxen_nic_disable_int(adapter); - if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { - /* claim interrupt */ - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - writel(our_int & ~((u32)(0x80 << adapter->portnum)), - NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - } - } - if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { if (netif_rx_schedule_prep(netdev)) { /* @@ -1298,6 +1280,7 @@ irqreturn_t netxen_intr(int irq, void *data) { struct netxen_adapter *adapter; struct net_device *netdev; + u32 our_int = 0; if (unlikely(!irq)) { return IRQ_NONE; /* Not our interrupt */ @@ -1305,7 +1288,22 @@ irqreturn_t netxen_intr(int irq, void *data) adapter = (struct netxen_adapter *)data; netdev = adapter->netdev; - /* process our status queue (for all 4 ports) */ + + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + /* not our interrupt */ + if ((our_int & (0x80 << adapter->portnum)) == 0) + return IRQ_NONE; + } + + if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { + /* claim interrupt */ + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + writel(our_int & ~((u32)(0x80 << adapter->portnum)), + NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + } + } + if (netif_running(netdev)) netxen_handle_int(adapter, netdev); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 73da611fd53..997c2d0c83b 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -996,7 +996,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; mace_private *lp = netdev_priv(dev); - kio_addr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr; int status; int IntrCnt = MACE_MAX_IR_ITERATIONS; @@ -1006,6 +1006,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) return IRQ_NONE; } + ioaddr = dev->base_addr; + if (lp->tx_irq_disabled) { printk( (lp->tx_irq_disabled? diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 7912dbd1425..af6728cb49c 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1368,6 +1368,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; u_short num_pages; short time_out, ir; + unsigned long flags; netif_stop_queue(dev); @@ -1395,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* A packet is now waiting. */ smc->packets_waiting++; + spin_lock_irqsave(&smc->lock, flags); SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */ /* need MC_RESET to keep the memory consistent. errata? */ @@ -1411,6 +1413,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Acknowledge the interrupt, send the packet. */ outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT); smc_hardware_send_packet(dev); /* Send the packet now.. */ + spin_unlock_irqrestore(&smc->lock, flags); return 0; } } @@ -1418,6 +1421,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Otherwise defer until the Tx-space-allocated interrupt. */ DEBUG(2, "%s: memory allocation deferred.\n", dev->name); outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT); + spin_unlock_irqrestore(&smc->lock, flags); return 0; } @@ -1523,6 +1527,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name, irq, ioaddr); + spin_lock(&smc->lock); smc->watchdog = 0; saved_bank = inw(ioaddr + BANK_SELECT); if ((saved_bank & 0xff00) != 0x3300) { @@ -1620,6 +1625,7 @@ irq_done: readb(smc->base+MEGAHERTZ_ISR); } #endif + spin_unlock(&smc->lock); return IRQ_RETVAL(handled); } @@ -1902,6 +1908,9 @@ static void media_check(u_long arg) kio_addr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; u_short link; + unsigned long flags; + + spin_lock_irqsave(&smc->lock, flags); saved_bank = inw(ioaddr + BANK_SELECT); @@ -1934,6 +1943,7 @@ static void media_check(u_long arg) smc->media.expires = jiffies + HZ/100; add_timer(&smc->media); SMC_SELECT_BANK(saved_bank); + spin_unlock_irqrestore(&smc->lock, flags); return; } @@ -2007,6 +2017,7 @@ reschedule: smc->media.expires = jiffies + HZ; add_timer(&smc->media); SMC_SELECT_BANK(saved_bank); + spin_unlock_irqrestore(&smc->lock, flags); } static int smc_link_ok(struct net_device *dev) @@ -2094,14 +2105,14 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) ret = mii_ethtool_gset(&smc->mii_if, ecmd); else ret = smc_netdev_get_ecmd(dev, ecmd); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } @@ -2112,14 +2123,14 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) ret = mii_ethtool_sset(&smc->mii_if, ecmd); else ret = smc_netdev_set_ecmd(dev, ecmd); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } @@ -2130,11 +2141,11 @@ static u32 smc_get_link(struct net_device *dev) u16 saved_bank = inw(ioaddr + BANK_SELECT); u32 ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); ret = smc_link_ok(dev); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 4cb710bbe72..cfa26791447 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h @@ -747,10 +747,9 @@ struct XENA_dev_config { #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) #define MC_ERR_REG_SM_ERR BIT(31) #define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\ - BIT(6) | BIT(7) | BIT(17) | BIT(19)) + BIT(17) | BIT(19)) #define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\ - BIT(13) | BIT(14) | BIT(15) |\ - BIT(18) | BIT(20)) + BIT(13) | BIT(18) | BIT(20)) u64 mc_err_mask; u64 mc_err_alarm; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index afef6c0c59f..2be0a0f1b48 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -32,12 +32,12 @@ * rx_ring_sz: This defines the number of receive blocks each ring can have. * This is also an array of size 8. * rx_ring_mode: This defines the operation mode of all 8 rings. The valid - * values are 1, 2 and 3. + * values are 1, 2. * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. * tx_fifo_len: This too is an array of 8. Each element defines the number of * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), - * 1(MSI), 2(MSI_X). Default value is '0(INTA)' + * 2(MSI_X). Default value is '0(INTA)' * lro: Specifies whether to enable Large Receive Offload (LRO) or not. * Possible values '1' for enable '0' for disable. Default is '0' * lro_max_pkts: This parameter defines maximum number of packets can be @@ -84,14 +84,14 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.23.1" +#define DRV_VERSION "2.0.25.1" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; static char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[4] = {32,48,48,64}; -static int rxd_count[4] = {127,85,85,63}; +static int rxd_size[2] = {32,48}; +static int rxd_count[2] = {127,85}; static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) { @@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { ("lro_flush_due_to_max_pkts"), ("lro_avg_aggr_pkts"), ("mem_alloc_fail_cnt"), + ("pci_map_fail_cnt"), ("watchdog_timer_cnt"), ("mem_allocated"), ("mem_freed"), @@ -426,7 +427,7 @@ S2IO_PARM_INT(bimodal, 0); S2IO_PARM_INT(l3l4hdr_size, 128); /* Frequency of Rx desc syncs expressed as power of 2 */ S2IO_PARM_INT(rxsync_frequency, 3); -/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ +/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 0); /* Large receive offload feature */ S2IO_PARM_INT(lro, 0); @@ -701,7 +702,7 @@ static int init_shared_mem(struct s2io_nic *nic) (u64) tmp_p_addr_next; } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* * Allocation of Storages for buffer addresses in 2BUFF mode * and the buffers as well. @@ -870,7 +871,7 @@ static void free_shared_mem(struct s2io_nic *nic) } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* Freeing buffer storage addresses in 2BUFF mode. */ for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -2233,44 +2234,6 @@ static void stop_nic(struct s2io_nic *nic) writeq(val64, &bar0->adapter_control); } -static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \ - sk_buff *skb) -{ - struct net_device *dev = nic->dev; - struct sk_buff *frag_list; - void *tmp; - - /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single - (nic->pdev, skb->data, l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); - - /* skb_shinfo(skb)->frag_list will have L4 data payload */ - skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); - if (skb_shinfo(skb)->frag_list == NULL) { - nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; - DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name); - return -ENOMEM ; - } - frag_list = skb_shinfo(skb)->frag_list; - skb->truesize += frag_list->truesize; - nic->mac_control.stats_info->sw_stat.mem_allocated - += frag_list->truesize; - frag_list->next = NULL; - tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1); - frag_list->data = tmp; - skb_reset_tail_pointer(frag_list); - - /* Buffer-2 receives L4 data payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, - frag_list->data, dev->mtu, - PCI_DMA_FROMDEVICE); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); - - return SUCCESS; -} - /** * fill_rx_buffers - Allocates the Rx side skbs * @nic: device private variable @@ -2307,6 +2270,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) unsigned long flags; struct RxD_t *first_rxdp = NULL; u64 Buffer0_ptr = 0, Buffer1_ptr = 0; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; + struct swStat *stats = &nic->mac_control.stats_info->sw_stat; mac_control = &nic->mac_control; config = &nic->config; @@ -2359,7 +2325,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; } if ((rxdp->Control_1 & RXD_OWN_XENA) && - ((nic->rxd_mode >= RXD_MODE_3A) && + ((nic->rxd_mode == RXD_MODE_3B) && (rxdp->Control_2 & BIT(0)))) { mac_control->rings[ring_no].rx_curr_put_info. offset = off; @@ -2370,10 +2336,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) HEADER_802_2_SIZE + HEADER_SNAP_SIZE; if (nic->rxd_mode == RXD_MODE_1) size += NET_IP_ALIGN; - else if (nic->rxd_mode == RXD_MODE_3B) - size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; + size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; /* allocate skb */ skb = dev_alloc_skb(size); @@ -2392,33 +2356,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) += skb->truesize; if (nic->rxd_mode == RXD_MODE_1) { /* 1 buffer mode - normal operation mode */ + rxdp1 = (struct RxD1*)rxdp; memset(rxdp, 0, sizeof(struct RxD1)); skb_reserve(skb, NET_IP_ALIGN); - ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single + rxdp1->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == + DMA_ERROR_CODE)) + goto pci_map_failed; + rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); - } else if (nic->rxd_mode >= RXD_MODE_3A) { + } else if (nic->rxd_mode == RXD_MODE_3B) { /* - * 2 or 3 buffer mode - - * Both 2 buffer mode and 3 buffer mode provides 128 + * 2 buffer mode - + * 2 buffer mode provides 128 * byte aligned receive buffers. - * - * 3 buffer mode provides header separation where in - * skb->data will have L3/L4 headers where as - * skb_shinfo(skb)->frag_list will have the L4 data - * payload */ + rxdp3 = (struct RxD3*)rxdp; /* save buffer pointers to avoid frequent dma mapping */ - Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr; - Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr; + Buffer0_ptr = rxdp3->Buffer0_ptr; + Buffer1_ptr = rxdp3->Buffer1_ptr; memset(rxdp, 0, sizeof(struct RxD3)); /* restore the buffer pointers for dma sync*/ - ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr; - ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr; + rxdp3->Buffer0_ptr = Buffer0_ptr; + rxdp3->Buffer1_ptr = Buffer1_ptr; ba = &mac_control->rings[ring_no].ba[block_no][off]; skb_reserve(skb, BUF0_LEN); @@ -2428,14 +2394,18 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - if (!(((struct RxD3*)rxdp)->Buffer0_ptr)) - ((struct RxD3*)rxdp)->Buffer0_ptr = + if (!(rxdp3->Buffer0_ptr)) + rxdp3->Buffer0_ptr = pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); else pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, + (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { /* Two buffer mode */ @@ -2444,33 +2414,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) * Buffer2 will have L3/L4 header plus * L4 payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single + rxdp3->Buffer2_ptr = pci_map_single (nic->pdev, skb->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - /* Buffer-1 will be dummy buffer. Not used */ - if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) { - ((struct RxD3*)rxdp)->Buffer1_ptr = + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + + rxdp3->Buffer1_ptr = pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single + (nic->pdev, + (dma_addr_t)skb->data, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); + goto pci_map_failed; } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 (dev->mtu + 4); - } else { - /* 3 buffer mode */ - if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) { - nic->mac_control.stats_info->sw_stat.\ - mem_freed += skb->truesize; - dev_kfree_skb_irq(skb); - if (first_rxdp) { - wmb(); - first_rxdp->Control_1 |= - RXD_OWN_XENA; - } - return -ENOMEM ; - } } rxdp->Control_2 |= BIT(0); } @@ -2505,6 +2472,11 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) } return SUCCESS; +pci_map_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; } static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) @@ -2515,6 +2487,8 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) struct RxD_t *rxdp; struct mac_info *mac_control; struct buffAdd *ba; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; mac_control = &sp->mac_control; for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) { @@ -2526,40 +2500,30 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) continue; } if (sp->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE - + HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); memset(rxdp, 0, sizeof(struct RxD1)); } else if(sp->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; ba = &mac_control->rings[ring_no]. ba[blk][j]; pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, - BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - BUF1_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(struct RxD3)); - } else { - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, + rxdp3->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu, + rxdp3->Buffer2_ptr, + dev->mtu + 4, PCI_DMA_FROMDEVICE); memset(rxdp, 0, sizeof(struct RxD3)); } @@ -2756,6 +2720,8 @@ static void rx_intr_handler(struct ring_info *ring_data) struct sk_buff *skb; int pkt_cnt = 0; int i; + struct RxD1* rxdp1; + struct RxD3* rxdp3; spin_lock(&nic->rx_lock); if (atomic_read(&nic->card_state) == CARD_DOWN) { @@ -2796,32 +2762,23 @@ static void rx_intr_handler(struct ring_info *ring_data) return; } if (nic->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE + - HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, - BUF0_LEN, PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - } else { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu, PCI_DMA_FROMDEVICE); + rxdp3->Buffer2_ptr, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); } prefetch(skb->data); rx_osm_handler(ring_data, rxdp); @@ -3425,23 +3382,8 @@ static void s2io_reset(struct s2io_nic * sp) /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); - if (sp->device_type == XFRAME_II_DEVICE) { - int ret; - ret = pci_set_power_state(sp->pdev, 3); - if (!ret) - ret = pci_set_power_state(sp->pdev, 0); - else { - DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n", - __FUNCTION__); - goto old_way; - } - msleep(20); - goto new_way; - } -old_way: val64 = SW_RESET_ALL; writeq(val64, &bar0->sw_reset); -new_way: if (strstr(sp->product_name, "CX4")) { msleep(750); } @@ -3731,56 +3673,6 @@ static void store_xmsi_data(struct s2io_nic *nic) } } -int s2io_enable_msi(struct s2io_nic *nic) -{ - struct XENA_dev_config __iomem *bar0 = nic->bar0; - u16 msi_ctrl, msg_val; - struct config_param *config = &nic->config; - struct net_device *dev = nic->dev; - u64 val64, tx_mat, rx_mat; - int i, err; - - val64 = readq(&bar0->pic_control); - val64 &= ~BIT(1); - writeq(val64, &bar0->pic_control); - - err = pci_enable_msi(nic->pdev); - if (err) { - DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n", - nic->dev->name); - return err; - } - - /* - * Enable MSI and use MSI-1 in stead of the standard MSI-0 - * for interrupt handling. - */ - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - msg_val ^= 0x1; - pci_write_config_word(nic->pdev, 0x4c, msg_val); - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - - pci_read_config_word(nic->pdev, 0x42, &msi_ctrl); - msi_ctrl |= 0x10; - pci_write_config_word(nic->pdev, 0x42, msi_ctrl); - - /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */ - tx_mat = readq(&bar0->tx_mat0_n[0]); - for (i=0; i<config->tx_fifo_num; i++) { - tx_mat |= TX_MAT_SET(i, 1); - } - writeq(tx_mat, &bar0->tx_mat0_n[0]); - - rx_mat = readq(&bar0->rx_mat); - for (i=0; i<config->rx_ring_num; i++) { - rx_mat |= RX_MAT_SET(i, 1); - } - writeq(rx_mat, &bar0->rx_mat); - - dev->irq = nic->pdev->irq; - return 0; -} - static int s2io_enable_msi_x(struct s2io_nic *nic) { struct XENA_dev_config __iomem *bar0 = nic->bar0; @@ -4001,6 +3893,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) struct mac_info *mac_control; struct config_param *config; int offload_type; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; mac_control = &sp->mac_control; config = &sp->config; @@ -4085,11 +3978,18 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, sp->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; + txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); if (offload_type == SKB_GSO_UDP) @@ -4146,6 +4046,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; +pci_map_failed: + stats->pci_map_fail_cnt++; + netif_stop_queue(dev); + stats->mem_freed += skb->truesize; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; } static void @@ -4186,39 +4093,6 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) return 0; } -static irqreturn_t s2io_msi_handle(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct s2io_nic *sp = dev->priv; - int i; - struct mac_info *mac_control; - struct config_param *config; - - atomic_inc(&sp->isr_cnt); - mac_control = &sp->mac_control; - config = &sp->config; - DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__); - - /* If Intr is because of Rx Traffic */ - for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); - - /* If Intr is because of Tx Traffic */ - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); - - /* - * If the Rx buffer count is below the panic threshold then - * reallocate the buffers from the interrupt handler itself, - * else schedule a tasklet to reallocate the buffers. - */ - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); - - atomic_dec(&sp->isr_cnt); - return IRQ_HANDLED; -} - static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) { struct ring_info *ring = (struct ring_info *)dev_id; @@ -4927,19 +4801,17 @@ static void s2io_ethtool_gringparam(struct net_device *dev, ering->rx_max_pending = MAX_RX_DESC_1; else if (sp->rxd_mode == RXD_MODE_3B) ering->rx_max_pending = MAX_RX_DESC_2; - else if (sp->rxd_mode == RXD_MODE_3A) - ering->rx_max_pending = MAX_RX_DESC_3; ering->tx_max_pending = MAX_TX_DESC; - for (i = 0 ; i < sp->config.tx_fifo_num ; i++) { + for (i = 0 ; i < sp->config.tx_fifo_num ; i++) tx_desc_count += sp->config.tx_cfg[i].fifo_len; - } + DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds); ering->tx_pending = tx_desc_count; rx_desc_count = 0; - for (i = 0 ; i < sp->config.rx_ring_num ; i++) { + for (i = 0 ; i < sp->config.rx_ring_num ; i++) rx_desc_count += sp->config.rx_cfg[i].num_rxd; - } + ering->rx_pending = rx_desc_count; ering->rx_mini_max_pending = 0; @@ -5923,6 +5795,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, else tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt; tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt; tmp_stats[i++] = stat_info->sw_stat.mem_allocated; tmp_stats[i++] = stat_info->sw_stat.mem_freed; @@ -6266,9 +6139,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, u64 *temp2, int size) { struct net_device *dev = sp->dev; - struct sk_buff *frag_list; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) { + struct RxD1 *rxdp1 = (struct RxD1 *)rxdp; /* allocate skb */ if (*skb) { DBG_PRINT(INFO_DBG, "SKB is not NULL\n"); @@ -6277,7 +6151,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * using same mapped address for the Rxd * buffer pointer */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0; + rxdp1->Buffer0_ptr = *temp0; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -6294,18 +6168,23 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * such it will be used for next rxd whose * Host Control is NULL */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 = + rxdp1->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { + struct RxD3 *rxdp3 = (struct RxD3 *)rxdp; /* Two buffer Mode */ if (*skb) { - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; + rxdp3->Buffer2_ptr = *temp2; + rxdp3->Buffer0_ptr = *temp0; + rxdp3->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -6318,73 +6197,47 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, } sp->mac_control.stats_info->sw_stat.mem_allocated += (*skb)->truesize; - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = + rxdp3->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } + rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); /* Buffer-1 will be dummy buffer not used */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = + rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, - PCI_DMA_FROMDEVICE); - } - } else if ((rxdp->Host_Control == 0)) { - /* Three buffer mode */ - if (*skb) { - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; - } else { - *skb = dev_alloc_skb(size); - if (!(*skb)) { - DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); - DBG_PRINT(INFO_DBG, "memory to allocate "); - DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n"); - sp->mac_control.stats_info->sw_stat. \ - mem_alloc_fail_cnt++; - return -ENOMEM; - } - sp->mac_control.stats_info->sw_stat.mem_allocated - += (*skb)->truesize; - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = - pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, - PCI_DMA_FROMDEVICE); - /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = - pci_map_single( sp->pdev, (*skb)->data, - l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); - /* - * skb_shinfo(skb)->frag_list will have L4 - * data payload - */ - skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu + - ALIGN_SIZE); - if (skb_shinfo(*skb)->frag_list == NULL) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ - failed\n ", dev->name); - sp->mac_control.stats_info->sw_stat. \ - mem_alloc_fail_cnt++; - return -ENOMEM ; + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; } - frag_list = skb_shinfo(*skb)->frag_list; - frag_list->next = NULL; - sp->mac_control.stats_info->sw_stat.mem_allocated - += frag_list->truesize; - /* - * Buffer-2 receives L4 data payload - */ - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = - pci_map_single( sp->pdev, frag_list->data, - dev->mtu, PCI_DMA_FROMDEVICE); } } return 0; + memalloc_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; } + static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, int size) { @@ -6395,10 +6248,6 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4); - } else { - rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); } } @@ -6420,8 +6269,6 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) size += NET_IP_ALIGN; else if (sp->rxd_mode == RXD_MODE_3B) size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; - else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -6431,7 +6278,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) for (k = 0; k < rxd_count[sp->rxd_mode]; k++) { rxdp = mac_control->rings[i]. rx_blocks[j].rxds[k].virt_addr; - if(sp->rxd_mode >= RXD_MODE_3A) + if(sp->rxd_mode == RXD_MODE_3B) ba = &mac_control->rings[i].ba[j][k]; if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb,(u64 *)&temp0_64, @@ -6458,9 +6305,7 @@ static int s2io_add_isr(struct s2io_nic * sp) struct net_device *dev = sp->dev; int err = 0; - if (sp->intr_type == MSI) - ret = s2io_enable_msi(sp); - else if (sp->intr_type == MSI_X) + if (sp->intr_type == MSI_X) ret = s2io_enable_msi_x(sp); if (ret) { DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); @@ -6471,16 +6316,6 @@ static int s2io_add_isr(struct s2io_nic * sp) store_xmsi_data(sp); /* After proper initialization of H/W, register ISR */ - if (sp->intr_type == MSI) { - err = request_irq((int) sp->pdev->irq, s2io_msi_handle, - IRQF_SHARED, sp->name, dev); - if (err) { - pci_disable_msi(sp->pdev); - DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n", - dev->name); - return -1; - } - } if (sp->intr_type == MSI_X) { int i, msix_tx_cnt=0,msix_rx_cnt=0; @@ -6567,14 +6402,6 @@ static void s2io_rem_isr(struct s2io_nic * sp) pci_disable_msix(sp->pdev); } else { free_irq(sp->pdev->irq, dev); - if (sp->intr_type == MSI) { - u16 val; - - pci_disable_msi(sp->pdev); - pci_read_config_word(sp->pdev, 0x4c, &val); - val ^= 0x1; - pci_write_config_word(sp->pdev, 0x4c, val); - } } /* Waiting till all Interrupt handlers are complete */ cnt = 0; @@ -6907,6 +6734,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) } /* Updating statistics */ + sp->stats.rx_packets++; rxdp->Host_Control = 0; if (sp->rxd_mode == RXD_MODE_1) { int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); @@ -6914,7 +6742,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) sp->stats.rx_bytes += len; skb_put(skb, len); - } else if (sp->rxd_mode >= RXD_MODE_3A) { + } else if (sp->rxd_mode == RXD_MODE_3B) { int get_block = ring_data->rx_curr_get_info.block_index; int get_off = ring_data->rx_curr_get_info.offset; int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2); @@ -6924,18 +6752,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) struct buffAdd *ba = &ring_data->ba[get_block][get_off]; sp->stats.rx_bytes += buf0_len + buf2_len; memcpy(buff, ba->ba_0, buf0_len); - - if (sp->rxd_mode == RXD_MODE_3A) { - int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2); - - skb_put(skb, buf1_len); - skb->len += buf2_len; - skb->data_len += buf2_len; - skb_put(skb_shinfo(skb)->frag_list, buf2_len); - sp->stats.rx_bytes += buf1_len; - - } else - skb_put(skb, buf2_len); + skb_put(skb, buf2_len); } if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) || @@ -7131,7 +6948,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) *dev_intr_type = INTA; } #else - if (*dev_intr_type > MSI_X) { + if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " "Defaulting to INTA\n"); *dev_intr_type = INTA; @@ -7145,10 +6962,10 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) *dev_intr_type = INTA; } - if (rx_ring_mode > 3) { + if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) { DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n"); - DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n"); - rx_ring_mode = 3; + DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n"); + rx_ring_mode = 1; } return SUCCESS; } @@ -7240,28 +7057,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) pci_disable_device(pdev); return -ENOMEM; } - if (dev_intr_type != MSI_X) { - if (pci_request_regions(pdev, s2io_driver_name)) { - DBG_PRINT(ERR_DBG, "Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - } - else { - if (!(request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - if (!(request_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n"); - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - pci_disable_device(pdev); - return -ENODEV; - } + if ((ret = pci_request_regions(pdev, s2io_driver_name))) { + DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret); + pci_disable_device(pdev); + return -ENODEV; } dev = alloc_etherdev(sizeof(struct s2io_nic)); @@ -7288,8 +7087,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->rxd_mode = RXD_MODE_1; if (rx_ring_mode == 2) sp->rxd_mode = RXD_MODE_3B; - if (rx_ring_mode == 3) - sp->rxd_mode = RXD_MODE_3A; sp->intr_type = dev_intr_type; @@ -7565,10 +7362,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n", dev->name); break; - case RXD_MODE_3A: - DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n", - dev->name); - break; } if (napi) @@ -7577,9 +7370,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) case INTA: DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); break; - case MSI: - DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); - break; case MSI_X: DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); break; @@ -7619,14 +7409,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) mem_alloc_failed: free_shared_mem(sp); pci_disable_device(pdev); - if (dev_intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); @@ -7661,14 +7444,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) free_shared_mem(sp); iounmap(sp->bar0); iounmap(sp->bar1); - if (sp->intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); pci_disable_device(pdev); diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 3887fe63a90..92983ee7df8 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -74,6 +74,10 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) +#ifndef DMA_ERROR_CODE +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) +#endif + /* Protocol assist features of the NIC */ #define L3_CKSUM_OK 0xFFFF #define L4_CKSUM_OK 0xFFFF @@ -97,6 +101,7 @@ struct swStat { unsigned long long num_aggregations; /* Other statistics */ unsigned long long mem_alloc_fail_cnt; + unsigned long long pci_map_fail_cnt; unsigned long long watchdog_timer_cnt; unsigned long long mem_allocated; unsigned long long mem_freed; @@ -575,8 +580,7 @@ struct RxD_block { #define SIZE_OF_BLOCK 4096 #define RXD_MODE_1 0 /* One Buffer mode */ -#define RXD_MODE_3A 1 /* Three Buffer mode */ -#define RXD_MODE_3B 2 /* Two Buffer mode */ +#define RXD_MODE_3B 1 /* Two Buffer mode */ /* Structure to hold virtual addresses of Buf0 and Buf1 in * 2buf mode. */ @@ -876,7 +880,6 @@ struct s2io_nic { u16 lro_max_aggr_per_sess; #define INTA 0 -#define MSI 1 #define MSI_X 2 u8 intr_type; @@ -1020,8 +1023,6 @@ static int s2io_poll(struct net_device *dev, int *budget); static void s2io_init_pci(struct s2io_nic * sp); static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static void s2io_alarm_handle(unsigned long data); -static int s2io_enable_msi(struct s2io_nic *nic); -static irqreturn_t s2io_msi_handle(int irq, void *dev_id); static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id); static irqreturn_t diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index a05fd97e5bc..04cba6bf3d5 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -768,11 +768,13 @@ done: static void write_bulk_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; - struct net_device *net = pegasus->net; + struct net_device *net; if (!pegasus) return; + net = pegasus->net; + if (!netif_device_present(net) || !netif_running(net)) return; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index fba319d6fcc..1ee9cd9c86e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1517,7 +1517,7 @@ EXPORT_SYMBOL(pcie_get_readrq); /** * pcie_set_readrq - set PCI Express maximum memory read request * @dev: PCI device to query - * @count: maximum memory read count in bytes + * @rq: maximum memory read count in bytes * valid values are 128, 256, 512, 1024, 2048, 4096 * * If possible sets maximum read byte count diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index befff5f9d58..ac49b15fa76 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_USB_SISUSBVGA) += misc/ obj-$(CONFIG_USB_TEST) += misc/ obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ obj-$(CONFIG_USB_USS720) += misc/ +obj-$(CONFIG_USB_IOWARRIOR) += misc/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 25f63f1096b..b6bd05e3d43 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -18,9 +18,17 @@ #include "hcd.h" /* for usbcore internals */ #include "usb.h" +struct api_context { + struct completion done; + int status; +}; + static void usb_api_blocking_completion(struct urb *urb) { - complete((struct completion *)urb->context); + struct api_context *ctx = urb->context; + + ctx->status = urb->status; + complete(&ctx->done); } @@ -32,20 +40,21 @@ static void usb_api_blocking_completion(struct urb *urb) */ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) { - struct completion done; + struct api_context ctx; unsigned long expire; int retval; - int status = urb->status; - init_completion(&done); - urb->context = &done; + init_completion(&ctx.done); + urb->context = &ctx; urb->actual_length = 0; retval = usb_submit_urb(urb, GFP_NOIO); if (unlikely(retval)) goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&done, expire)) { + if (!wait_for_completion_timeout(&ctx.done, expire)) { + usb_kill_urb(urb); + retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); dev_dbg(&urb->dev->dev, "%s timed out on ep%d%s len=%d/%d\n", @@ -54,11 +63,8 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) usb_pipein(urb->pipe) ? "in" : "out", urb->actual_length, urb->transfer_buffer_length); - - usb_kill_urb(urb); - retval = status == -ENOENT ? -ETIMEDOUT : status; } else - retval = status; + retval = ctx.status; out: if (actual_length) *actual_length = urb->actual_length; @@ -411,15 +417,22 @@ int usb_sg_init ( * Some systems need to revert to PIO when DMA is temporarily * unavailable. For their sakes, both transfer_buffer and * transfer_dma are set when possible. However this can only - * work on systems without HIGHMEM, since DMA buffers located - * in high memory are not directly addressable by the CPU for - * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL + * work on systems without: + * + * - HIGHMEM, since DMA buffers located in high memory are + * not directly addressable by the CPU for PIO; + * + * - IOMMU, since dma_map_sg() is allowed to use an IOMMU to + * make virtually discontiguous buffers be "dma-contiguous" + * so that PIO and DMA need diferent numbers of URBs. + * + * So when HIGHMEM or IOMMU are in use, transfer_buffer is NULL * to prevent stale pointers and to help spot bugs. */ if (dma) { io->urbs [i]->transfer_dma = sg_dma_address (sg + i); len = sg_dma_len (sg + i); -#ifdef CONFIG_HIGHMEM +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU) io->urbs[i]->transfer_buffer = NULL; #else io->urbs[i]->transfer_buffer = diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index aa21b38a31c..b7917c5a3c6 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -30,18 +30,40 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ + { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Benq S2W 3300U */ { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N1240U/LiDE30 */ + { USB_DEVICE(0x04a9, 0x220e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N650U/N656U */ + { USB_DEVICE(0x04a9, 0x2206), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan 1220U */ + { USB_DEVICE(0x04a9, 0x2207), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N670U/N676U/LiDE 20 */ + { USB_DEVICE(0x04a9, 0x220d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* old Cannon scanner */ + { USB_DEVICE(0x04a9, 0x2220), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp. Perfection 1200 */ { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp. Perfection 660 */ + { USB_DEVICE(0x04b8, 0x0114), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Epson Perfection 1260 Photo */ + { USB_DEVICE(0x04b8, 0x011d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp - Perfection 1670 */ { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* EPSON Perfection 2480 */ + { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp.*/ + { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Samsung ML-2510 Series printer */ { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Elsa MicroLink 56k (V.250) */ { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Ultima Electronics Corp.*/ { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Agfa Snapscan1212u */ + { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Umax [hex] Astra 3400U */ { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index d18901b92cd..c6760aee1e5 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -50,7 +50,7 @@ usb_descriptor_fillbuf(void *buf, unsigned buflen, return -EINVAL; /* fill buffer from src[] until null descriptor ptr */ - for (; 0 != *src; src++) { + for (; NULL != *src; src++) { unsigned len = (*src)->bLength; if (len > buflen) diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6042364402b..3aa46cfa66b 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -71,7 +71,7 @@ ep_matches ( u16 max; /* endpoint already claimed? */ - if (0 != ep->driver_data) + if (NULL != ep->driver_data) return 0; /* only support ep0 for portable CONTROL traffic */ diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a3376739a81..593e23507b1 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1723,7 +1723,8 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) size += sizeof (struct rndis_packet_msg_type); size -= size % dev->out_ep->maxpacket; - if ((skb = alloc_skb (size + NET_IP_ALIGN, gfp_flags)) == 0) { + skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); + if (skb == NULL) { DEBUG (dev, "no rx skb\n"); goto enomem; } diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index e60745ffaf8..173004f60fe 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -964,7 +964,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) } if (len > sizeof (dev->rbuf)) req->buf = kmalloc(len, GFP_ATOMIC); - if (req->buf == 0) { + if (req->buf == NULL) { req->buf = dev->rbuf; return -ENOMEM; } @@ -1394,7 +1394,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->setup_abort = 0; if (dev->state == STATE_DEV_UNCONNECTED) { #ifdef CONFIG_USB_GADGET_DUALSPEED - if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { + if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == NULL) { spin_unlock(&dev->lock); ERROR (dev, "no high speed config??\n"); return -EINVAL; diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 700dda8a915..4b27d12f049 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1299,7 +1299,7 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, req->req.actual = 0; req->req.status = -EINPROGRESS; - if (ep->desc == 0) /* control */ + if (ep->desc == NULL) /* control */ start_ep0(ep, req); else { if (request && !ep->busy) diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 63b9521c132..72b4ebbf132 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -93,8 +93,6 @@ static const char driver_name [] = "pxa2xx_udc"; static const char ep0name [] = "ep0"; -// #define DISABLE_TEST_MODE - #ifdef CONFIG_ARCH_IXP4XX /* cpu-specific register addresses are compiled in to this code */ @@ -113,17 +111,6 @@ static const char ep0name [] = "ep0"; #define SIZE_STR "" #endif -#ifdef DISABLE_TEST_MODE -/* (mode == 0) == no undocumented chip tweaks - * (mode & 1) == double buffer bulk IN - * (mode & 2) == double buffer bulk OUT - * ... so mode = 3 (or 7, 15, etc) does it for both - */ -static ushort fifo_mode = 0; -module_param(fifo_mode, ushort, 0); -MODULE_PARM_DESC (fifo_mode, "pxa2xx udc fifo mode"); -#endif - /* --------------------------------------------------------------------------- * endpoint related parts of the api to the usb controller hardware, * used by gadget driver; and the inner talker-to-hardware core. @@ -1252,23 +1239,6 @@ static void udc_enable (struct pxa2xx_udc *dev) UDC_RES2 = 0x00; } -#ifdef DISABLE_TEST_MODE - /* "test mode" seems to have become the default in later chip - * revs, preventing double buffering (and invalidating docs). - * this EXPERIMENT enables it for bulk endpoints by tweaking - * undefined/reserved register bits (that other drivers clear). - * Belcarra code comments noted this usage. - */ - if (fifo_mode & 1) { /* IN endpoints */ - UDC_RES1 |= USIR0_IR1|USIR0_IR6; - UDC_RES2 |= USIR1_IR11; - } - if (fifo_mode & 2) { /* OUT endpoints */ - UDC_RES1 |= USIR0_IR2|USIR0_IR7; - UDC_RES2 |= USIR1_IR12; - } -#endif - /* enable suspend/resume and reset irqs */ udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a2e6e3fc8c8..fcfe869acb9 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -653,7 +653,8 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; - if (source_sink_start_ep (ep, gfp_flags) != 0) { + if (source_sink_start_ep(ep, gfp_flags) + != NULL) { dev->in_ep = ep; continue; } @@ -667,7 +668,8 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; - if (source_sink_start_ep (ep, gfp_flags) != 0) { + if (source_sink_start_ep(ep, gfp_flags) + != NULL) { dev->out_ep = ep; continue; } diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index e831cb7f64f..33f6ee50b8d 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -356,7 +356,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - port %d", __FUNCTION__, port->number); - if ((!port->tty) || (!port->tty->termios)) { + if (!port->tty || !port->tty->termios) { dbg("%s - no tty structures", __FUNCTION__); return; } @@ -526,50 +526,35 @@ static void cp2101_set_termios (struct usb_serial_port *port, return; } cflag = port->tty->termios->c_cflag; - - /* Check that they really want us to change something */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(port->tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - nothing to change...", __FUNCTION__); - return; - } - - old_cflag = old_termios->c_cflag; - } + old_cflag = old_termios->c_cflag; + baud = tty_get_baud_rate(port->tty); /* If the baud rate is to be updated*/ - if ((cflag & CBAUD) != (old_cflag & CBAUD)) { - switch (cflag & CBAUD) { - /* - * The baud rates which are commented out below - * appear to be supported by the device - * but are non-standard - */ - case B0: baud = 0; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - /*case B7200: baud = 7200; break;*/ - case B9600: baud = 9600; break; - /*ase B14400: baud = 14400; break;*/ - case B19200: baud = 19200; break; - /*case B28800: baud = 28800; break;*/ - case B38400: baud = 38400; break; - /*case B55854: baud = 55054; break;*/ - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - /*case B127117: baud = 127117; break;*/ - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - case B921600: baud = 921600; break; - /*case B3686400: baud = 3686400; break;*/ + if (baud != tty_termios_baud_rate(old_termios)) { + switch (baud) { + case 0: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 7200: + case 9600: + case 14400: + case 19200: + case 28800: + case 38400: + case 55854: + case 57600: + case 115200: + case 127117: + case 230400: + case 460800: + case 921600: + case 3686400: + break; default: - dev_err(&port->dev, "cp2101 driver does not " - "support the baudrate requested\n"); + baud = 9600; break; } diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 976f54ec26e..dab2e66d111 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -433,38 +433,38 @@ struct digi_port { /* Local Function Declarations */ -static void digi_wakeup_write( struct usb_serial_port *port ); +static void digi_wakeup_write(struct usb_serial_port *port); static void digi_wakeup_write_lock(struct work_struct *work); -static int digi_write_oob_command( struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible ); -static int digi_write_inb_command( struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout ); -static int digi_set_modem_signals( struct usb_serial_port *port, - unsigned int modem_signals, int interruptible ); -static int digi_transmit_idle( struct usb_serial_port *port, - unsigned long timeout ); +static int digi_write_oob_command(struct usb_serial_port *port, + unsigned char *buf, int count, int interruptible); +static int digi_write_inb_command(struct usb_serial_port *port, + unsigned char *buf, int count, unsigned long timeout); +static int digi_set_modem_signals(struct usb_serial_port *port, + unsigned int modem_signals, int interruptible); +static int digi_transmit_idle(struct usb_serial_port *port, + unsigned long timeout); static void digi_rx_throttle (struct usb_serial_port *port); static void digi_rx_unthrottle (struct usb_serial_port *port); -static void digi_set_termios( struct usb_serial_port *port, - struct ktermios *old_termios ); -static void digi_break_ctl( struct usb_serial_port *port, int break_state ); -static int digi_ioctl( struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg ); -static int digi_tiocmget( struct usb_serial_port *port, struct file *file ); -static int digi_tiocmset( struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear ); -static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ); -static void digi_write_bulk_callback( struct urb *urb ); -static int digi_write_room( struct usb_serial_port *port ); -static int digi_chars_in_buffer( struct usb_serial_port *port ); -static int digi_open( struct usb_serial_port *port, struct file *filp ); -static void digi_close( struct usb_serial_port *port, struct file *filp ); -static int digi_startup_device( struct usb_serial *serial ); -static int digi_startup( struct usb_serial *serial ); -static void digi_shutdown( struct usb_serial *serial ); -static void digi_read_bulk_callback( struct urb *urb ); -static int digi_read_inb_callback( struct urb *urb ); -static int digi_read_oob_callback( struct urb *urb ); +static void digi_set_termios(struct usb_serial_port *port, + struct ktermios *old_termios); +static void digi_break_ctl(struct usb_serial_port *port, int break_state); +static int digi_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg); +static int digi_tiocmget(struct usb_serial_port *port, struct file *file); +static int digi_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear); +static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count); +static void digi_write_bulk_callback(struct urb *urb); +static int digi_write_room(struct usb_serial_port *port); +static int digi_chars_in_buffer(struct usb_serial_port *port); +static int digi_open(struct usb_serial_port *port, struct file *filp); +static void digi_close(struct usb_serial_port *port, struct file *filp); +static int digi_startup_device(struct usb_serial *serial); +static int digi_startup(struct usb_serial *serial); +static void digi_shutdown(struct usb_serial *serial); +static void digi_read_bulk_callback(struct urb *urb); +static int digi_read_inb_callback(struct urb *urb); +static int digi_read_oob_callback(struct urb *urb); /* Statics */ @@ -576,9 +576,9 @@ static struct usb_serial_driver digi_acceleport_4_device = { * with the equivalent code. */ -static inline long cond_wait_interruptible_timeout_irqrestore( +static long cond_wait_interruptible_timeout_irqrestore( wait_queue_head_t *q, long timeout, - spinlock_t *lock, unsigned long flags ) + spinlock_t *lock, unsigned long flags) { DEFINE_WAIT(wait); @@ -600,18 +600,16 @@ static inline long cond_wait_interruptible_timeout_irqrestore( static void digi_wakeup_write_lock(struct work_struct *work) { - struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); + struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work); struct usb_serial_port *port = priv->dp_port; unsigned long flags; - - spin_lock_irqsave( &priv->dp_port_lock, flags ); - digi_wakeup_write( port ); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); + digi_wakeup_write(port); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); } -static void digi_wakeup_write( struct usb_serial_port *port ) +static void digi_wakeup_write(struct usb_serial_port *port) { tty_wakeup(port->tty); } @@ -628,8 +626,8 @@ static void digi_wakeup_write( struct usb_serial_port *port ) * returned by usb_submit_urb. */ -static int digi_write_oob_command( struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible ) +static int digi_write_oob_command(struct usb_serial_port *port, + unsigned char *buf, int count, int interruptible) { int ret = 0; @@ -638,49 +636,37 @@ static int digi_write_oob_command( struct usb_serial_port *port, struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); unsigned long flags = 0; + dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count); -dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count ); - - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - - while( count > 0 ) { - - while( oob_port->write_urb->status == -EINPROGRESS - || oob_priv->dp_write_urb_in_use ) { + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + while(count > 0) { + while(oob_port->write_urb->status == -EINPROGRESS + || oob_priv->dp_write_urb_in_use) { cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags ); - if( interruptible && signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); + &oob_priv->dp_port_lock, flags); + if (interruptible && signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); } /* len must be a multiple of 4, so commands are not split */ - len = min(count, oob_port->bulk_out_size ); - if( len > 4 ) + len = min(count, oob_port->bulk_out_size); + if (len > 4) len &= ~3; - - memcpy( oob_port->write_urb->transfer_buffer, buf, len ); + memcpy(oob_port->write_urb->transfer_buffer, buf, len); oob_port->write_urb->transfer_buffer_length = len; oob_port->write_urb->dev = port->serial->dev; - - if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { oob_priv->dp_write_urb_in_use = 1; count -= len; buf += len; } - - } - - spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, - ret ); } - - return( ret ); + spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + return ret; } @@ -697,63 +683,58 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co * error returned by digi_write. */ -static int digi_write_inb_command( struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout ) +static int digi_write_inb_command(struct usb_serial_port *port, + unsigned char *buf, int count, unsigned long timeout) { - int ret = 0; int len; struct digi_port *priv = usb_get_serial_port_data(port); unsigned char *data = port->write_urb->transfer_buffer; unsigned long flags = 0; + dbg("digi_write_inb_command: TOP: port=%d, count=%d", + priv->dp_port_num, count); -dbg( "digi_write_inb_command: TOP: port=%d, count=%d", priv->dp_port_num, -count ); - - if( timeout ) + if (timeout) timeout += jiffies; else timeout = ULONG_MAX; - spin_lock_irqsave( &priv->dp_port_lock, flags ); - - while( count > 0 && ret == 0 ) { - - while( (port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { + spin_lock_irqsave(&priv->dp_port_lock, flags); + while(count > 0 && ret == 0) { + while((port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { cond_wait_interruptible_timeout_irqrestore( &port->write_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } /* len must be a multiple of 4 and small enough to */ /* guarantee the write will send buffered data first, */ /* so commands are in order with data and not split */ - len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len ); - if( len > 4 ) + len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); + if (len > 4) len &= ~3; /* write any buffered data first */ - if( priv->dp_out_buf_len > 0 ) { + if (priv->dp_out_buf_len > 0) { data[0] = DIGI_CMD_SEND_DATA; data[1] = priv->dp_out_buf_len; - memcpy( data+2, priv->dp_out_buf, - priv->dp_out_buf_len ); - memcpy( data+2+priv->dp_out_buf_len, buf, len ); + memcpy(data + 2, priv->dp_out_buf, + priv->dp_out_buf_len); + memcpy(data + 2 + priv->dp_out_buf_len, buf, len); port->write_urb->transfer_buffer_length - = priv->dp_out_buf_len+2+len; + = priv->dp_out_buf_len + 2 + len; } else { - memcpy( data, buf, len ); + memcpy(data, buf, len); port->write_urb->transfer_buffer_length = len; } port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; count -= len; @@ -761,16 +742,12 @@ count ); } } + spin_unlock_irqrestore(&priv->dp_port_lock, flags); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - - return( ret ); - + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); + return ret; } @@ -784,8 +761,8 @@ count ); * returned by usb_submit_urb. */ -static int digi_set_modem_signals( struct usb_serial_port *port, - unsigned int modem_signals, int interruptible ) +static int digi_set_modem_signals(struct usb_serial_port *port, + unsigned int modem_signals, int interruptible) { int ret; @@ -796,60 +773,47 @@ static int digi_set_modem_signals( struct usb_serial_port *port, unsigned long flags = 0; -dbg( "digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", -port_priv->dp_port_num, modem_signals ); + dbg("digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", + port_priv->dp_port_num, modem_signals); - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - spin_lock( &port_priv->dp_port_lock ); + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + spin_lock(&port_priv->dp_port_lock); - while( oob_port->write_urb->status == -EINPROGRESS - || oob_priv->dp_write_urb_in_use ) { - spin_unlock( &port_priv->dp_port_lock ); + while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) { + spin_unlock(&port_priv->dp_port_lock); cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags ); - if( interruptible && signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - spin_lock( &port_priv->dp_port_lock ); + &oob_priv->dp_port_lock, flags); + if (interruptible && signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + spin_lock(&port_priv->dp_port_lock); } - data[0] = DIGI_CMD_SET_DTR_SIGNAL; data[1] = port_priv->dp_port_num; - data[2] = (modem_signals&TIOCM_DTR) ? - DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; + data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; data[3] = 0; - data[4] = DIGI_CMD_SET_RTS_SIGNAL; data[5] = port_priv->dp_port_num; - data[6] = (modem_signals&TIOCM_RTS) ? - DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; + data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; data[7] = 0; oob_port->write_urb->transfer_buffer_length = 8; oob_port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { oob_priv->dp_write_urb_in_use = 1; port_priv->dp_modem_signals = (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); } - - spin_unlock( &port_priv->dp_port_lock ); - spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, - ret ); - } - - return( ret ); - + spin_unlock(&port_priv->dp_port_lock); + spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + return ret; } - /* * Digi Transmit Idle * @@ -862,203 +826,182 @@ port_priv->dp_port_num, modem_signals ); * port at a time, so its ok. */ -static int digi_transmit_idle( struct usb_serial_port *port, - unsigned long timeout ) +static int digi_transmit_idle(struct usb_serial_port *port, + unsigned long timeout) { - int ret; unsigned char buf[2]; struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; - - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_transmit_idle = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); buf[0] = DIGI_CMD_TRANSMIT_IDLE; buf[1] = 0; timeout += jiffies; - if( (ret=digi_write_inb_command( port, buf, 2, timeout-jiffies )) != 0 ) - return( ret ); + if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0) + return ret; - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); - while( time_before(jiffies, timeout) && !priv->dp_transmit_idle ) { + while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) { cond_wait_interruptible_timeout_irqrestore( &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } - priv->dp_transmit_idle = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - return( 0 ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return 0; } -static void digi_rx_throttle( struct usb_serial_port *port ) +static void digi_rx_throttle(struct usb_serial_port *port) { - unsigned long flags; struct digi_port *priv = usb_get_serial_port_data(port); -dbg( "digi_rx_throttle: TOP: port=%d", priv->dp_port_num ); + dbg("digi_rx_throttle: TOP: port=%d", priv->dp_port_num); /* stop receiving characters by not resubmitting the read urb */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_throttled = 1; priv->dp_throttle_restart = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - + spin_unlock_irqrestore(&priv->dp_port_lock, flags); } -static void digi_rx_unthrottle( struct usb_serial_port *port ) +static void digi_rx_unthrottle(struct usb_serial_port *port) { - int ret = 0; unsigned long flags; struct digi_port *priv = usb_get_serial_port_data(port); -dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); + dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* turn throttle off */ priv->dp_throttled = 0; priv->dp_throttle_restart = 0; /* restart read chain */ - if( priv->dp_throttle_restart ) { + if (priv->dp_throttle_restart) { port->read_urb->dev = port->serial->dev; - ret = usb_submit_urb( port->read_urb, GFP_ATOMIC ); + ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); } - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } -static void digi_set_termios( struct usb_serial_port *port, - struct ktermios *old_termios ) +static void digi_set_termios(struct usb_serial_port *port, + struct ktermios *old_termios) { struct digi_port *priv = usb_get_serial_port_data(port); - unsigned int iflag = port->tty->termios->c_iflag; - unsigned int cflag = port->tty->termios->c_cflag; + struct tty_struct *tty = port->tty; + unsigned int iflag = tty->termios->c_iflag; + unsigned int cflag = tty->termios->c_cflag; unsigned int old_iflag = old_termios->c_iflag; unsigned int old_cflag = old_termios->c_cflag; unsigned char buf[32]; unsigned int modem_signals; int arg,ret; int i = 0; + speed_t baud; - -dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag ); + dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag); /* set baud rate */ - if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { - + if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) { arg = -1; /* reassert DTR and (maybe) RTS on transition from B0 */ - if( (old_cflag&CBAUD) == B0 ) { + if ((old_cflag&CBAUD) == B0) { /* don't set RTS if using hardware flow control */ /* and throttling input */ modem_signals = TIOCM_DTR; - if( !(port->tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &port->tty->flags) ) { + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) modem_signals |= TIOCM_RTS; - } - digi_set_modem_signals( port, modem_signals, 1 ); + digi_set_modem_signals(port, modem_signals, 1); } - - switch( (cflag&CBAUD) ) { + switch (baud) { /* drop DTR and RTS on transition to B0 */ - case B0: digi_set_modem_signals( port, 0, 1 ); break; - case B50: arg = DIGI_BAUD_50; break; - case B75: arg = DIGI_BAUD_75; break; - case B110: arg = DIGI_BAUD_110; break; - case B150: arg = DIGI_BAUD_150; break; - case B200: arg = DIGI_BAUD_200; break; - case B300: arg = DIGI_BAUD_300; break; - case B600: arg = DIGI_BAUD_600; break; - case B1200: arg = DIGI_BAUD_1200; break; - case B1800: arg = DIGI_BAUD_1800; break; - case B2400: arg = DIGI_BAUD_2400; break; - case B4800: arg = DIGI_BAUD_4800; break; - case B9600: arg = DIGI_BAUD_9600; break; - case B19200: arg = DIGI_BAUD_19200; break; - case B38400: arg = DIGI_BAUD_38400; break; - case B57600: arg = DIGI_BAUD_57600; break; - case B115200: arg = DIGI_BAUD_115200; break; - case B230400: arg = DIGI_BAUD_230400; break; - case B460800: arg = DIGI_BAUD_460800; break; - default: - dbg( "digi_set_termios: can't handle baud rate 0x%x", - (cflag&CBAUD) ); - break; + case 0: digi_set_modem_signals(port, 0, 1); break; + case 50: arg = DIGI_BAUD_50; break; + case 75: arg = DIGI_BAUD_75; break; + case 110: arg = DIGI_BAUD_110; break; + case 150: arg = DIGI_BAUD_150; break; + case 200: arg = DIGI_BAUD_200; break; + case 300: arg = DIGI_BAUD_300; break; + case 600: arg = DIGI_BAUD_600; break; + case 1200: arg = DIGI_BAUD_1200; break; + case 1800: arg = DIGI_BAUD_1800; break; + case 2400: arg = DIGI_BAUD_2400; break; + case 4800: arg = DIGI_BAUD_4800; break; + case 9600: arg = DIGI_BAUD_9600; break; + case 19200: arg = DIGI_BAUD_19200; break; + case 38400: arg = DIGI_BAUD_38400; break; + case 57600: arg = DIGI_BAUD_57600; break; + case 115200: arg = DIGI_BAUD_115200; break; + case 230400: arg = DIGI_BAUD_230400; break; + case 460800: arg = DIGI_BAUD_460800; break; + default: + arg = DIGI_BAUD_9600; + baud = 9600; + break; } - - if( arg != -1 ) { + if (arg != -1) { buf[i++] = DIGI_CMD_SET_BAUD_RATE; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; } - } - /* set parity */ - if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) { - - if( (cflag&PARENB) ) { - if( (cflag&PARODD) ) + if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { + if (cflag&PARENB) { + if (cflag&PARODD) arg = DIGI_PARITY_ODD; else arg = DIGI_PARITY_EVEN; } else { arg = DIGI_PARITY_NONE; } - buf[i++] = DIGI_CMD_SET_PARITY; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } - /* set word size */ - if( (cflag&CSIZE) != (old_cflag&CSIZE) ) { - + if ((cflag&CSIZE) != (old_cflag&CSIZE)) { arg = -1; - - switch( (cflag&CSIZE) ) { + switch (cflag&CSIZE) { case CS5: arg = DIGI_WORD_SIZE_5; break; case CS6: arg = DIGI_WORD_SIZE_6; break; case CS7: arg = DIGI_WORD_SIZE_7; break; case CS8: arg = DIGI_WORD_SIZE_8; break; default: - dbg( "digi_set_termios: can't handle word size %d", - (cflag&CSIZE) ); + dbg("digi_set_termios: can't handle word size %d", + (cflag&CSIZE)); break; } - if( arg != -1 ) { + if (arg != -1) { buf[i++] = DIGI_CMD_SET_WORD_SIZE; buf[i++] = priv->dp_port_num; buf[i++] = arg; @@ -1068,9 +1011,9 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } /* set stop bits */ - if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) { + if ((cflag&CSTOPB) != (old_cflag&CSTOPB)) { - if( (cflag&CSTOPB) ) + if ((cflag&CSTOPB)) arg = DIGI_STOP_BITS_2; else arg = DIGI_STOP_BITS_1; @@ -1083,18 +1026,15 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } /* set input flow control */ - if( (iflag&IXOFF) != (old_iflag&IXOFF) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { - + if ((iflag&IXOFF) != (old_iflag&IXOFF) + || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { arg = 0; - - if( (iflag&IXOFF) ) + if (iflag&IXOFF) arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF; else arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF; - if( (cflag&CRTSCTS) ) { - + if (cflag&CRTSCTS) { arg |= DIGI_INPUT_FLOW_CONTROL_RTS; /* On USB-4 it is necessary to assert RTS prior */ @@ -1107,43 +1047,37 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } else { arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS; } - buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } /* set output flow control */ - if( (iflag&IXON) != (old_iflag&IXON) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { - + if ((iflag&IXON) != (old_iflag&IXON) + || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { arg = 0; - - if( (iflag&IXON) ) + if (iflag&IXON) arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; else arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; - if( (cflag&CRTSCTS) ) { + if (cflag&CRTSCTS) { arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; } else { arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; - port->tty->hw_stopped = 0; + tty->hw_stopped = 0; } buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } /* set receive enable/disable */ - if( (cflag&CREAD) != (old_cflag&CREAD) ) { - - if( (cflag&CREAD) ) + if ((cflag&CREAD) != (old_cflag&CREAD)) { + if (cflag&CREAD) arg = DIGI_ENABLE; else arg = DIGI_DISABLE; @@ -1152,32 +1086,26 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } - - if( (ret=digi_write_oob_command( port, buf, i, 1 )) != 0 ) - dbg( "digi_set_termios: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0) + dbg("digi_set_termios: write oob failed, ret=%d", ret); } -static void digi_break_ctl( struct usb_serial_port *port, int break_state ) +static void digi_break_ctl(struct usb_serial_port *port, int break_state) { - unsigned char buf[4]; - buf[0] = DIGI_CMD_BREAK_CONTROL; buf[1] = 2; /* length */ buf[2] = break_state ? 1 : 0; buf[3] = 0; /* pad */ - - digi_write_inb_command( port, buf, 4, 0 ); - + digi_write_inb_command(port, buf, 4, 0); } -static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) +static int digi_tiocmget(struct usb_serial_port *port, struct file *file) { struct digi_port *priv = usb_get_serial_port_data(port); unsigned int val; @@ -1185,15 +1113,15 @@ static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); val = priv->dp_modem_signals; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); return val; } -static int digi_tiocmset( struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear ) +static int digi_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear) { struct digi_port *priv = usb_get_serial_port_data(port); unsigned int val; @@ -1201,41 +1129,34 @@ static int digi_tiocmset( struct usb_serial_port *port, struct file *file, dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); val = (priv->dp_modem_signals & ~clear) | set; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return digi_set_modem_signals( port, val, 1 ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return digi_set_modem_signals(port, val, 1); } -static int digi_ioctl( struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg ) +static int digi_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) { - struct digi_port *priv = usb_get_serial_port_data(port); - -dbg( "digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd ); + dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd); switch (cmd) { - case TIOCMIWAIT: /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ /* TODO */ - return( 0 ); - + return 0; case TIOCGICOUNT: /* return count of modemline transitions */ /* TODO */ return 0; - } - - return( -ENOIOCTLCMD ); + return -ENOIOCTLCMD; } - -static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ) +static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count) { int ret,data_len,new_len; @@ -1243,35 +1164,29 @@ static int digi_write( struct usb_serial_port *port, const unsigned char *buf, i unsigned char *data = port->write_urb->transfer_buffer; unsigned long flags = 0; - -dbg( "digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", -priv->dp_port_num, count, in_interrupt() ); + dbg("digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", + priv->dp_port_num, count, in_interrupt()); /* copy user data (which can sleep) before getting spin lock */ - count = min( count, port->bulk_out_size-2 ); - count = min( 64, count); + count = min(count, port->bulk_out_size-2); + count = min(64, count); /* be sure only one write proceeds at a time */ /* there are races on the port private buffer */ /* and races to check write_urb->status */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* wait for urb status clear to submit another urb */ - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) { - + if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) { /* buffer data if count is 1 (probably put_char) if possible */ - if( count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE ) { + if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; new_len = 1; } else { new_len = 0; } - - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - return( new_len ); - + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return new_len; } /* allow space for any buffered data and for new data, up to */ @@ -1279,9 +1194,9 @@ priv->dp_port_num, count, in_interrupt() ); new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); data_len = new_len + priv->dp_out_buf_len; - if( data_len == 0 ) { - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return( 0 ); + if (data_len == 0) { + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return 0; } port->write_urb->transfer_buffer_length = data_len+2; @@ -1291,32 +1206,29 @@ priv->dp_port_num, count, in_interrupt() ); *data++ = data_len; /* copy in buffered data first */ - memcpy( data, priv->dp_out_buf, priv->dp_out_buf_len ); + memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len); data += priv->dp_out_buf_len; /* copy in new data */ - memcpy( data, buf, new_len ); + memcpy(data, buf, new_len); - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; ret = new_len; priv->dp_out_buf_len = 0; } /* return length of new data written, or error */ - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - if( ret < 0 ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - -dbg( "digi_write: returning %d", ret ); - return( ret ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + if (ret < 0) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); + dbg("digi_write: returning %d", ret); + return ret; } - -static void digi_write_bulk_callback( struct urb *urb ) +static void digi_write_bulk_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1326,153 +1238,136 @@ static void digi_write_bulk_callback( struct urb *urb ) int ret = 0; int status = urb->status; - - dbg("digi_write_bulk_callback: TOP, urb status=%d", status); + dbg("digi_write_bulk_callback: TOP, urb->status=%d", status); /* port and serial sanity check */ - if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { + if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", __FUNCTION__, status); return; } serial = port->serial; - if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) { + if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) { err("%s: serial or serial->private is NULL, status=%d", __FUNCTION__, status); return; } /* handle oob callback */ - if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { - dbg( "digi_write_bulk_callback: oob callback" ); - spin_lock( &priv->dp_port_lock ); + if (priv->dp_port_num == serial_priv->ds_oob_port_num) { + dbg("digi_write_bulk_callback: oob callback"); + spin_lock(&priv->dp_port_lock); priv->dp_write_urb_in_use = 0; - wake_up_interruptible( &port->write_wait ); - spin_unlock( &priv->dp_port_lock ); + wake_up_interruptible(&port->write_wait); + spin_unlock(&priv->dp_port_lock); return; } /* try to send any buffered data on this port, if it is open */ - spin_lock( &priv->dp_port_lock ); + spin_lock(&priv->dp_port_lock); priv->dp_write_urb_in_use = 0; - if( port->open_count && port->write_urb->status != -EINPROGRESS - && priv->dp_out_buf_len > 0 ) { - + if (port->open_count && port->write_urb->status != -EINPROGRESS + && priv->dp_out_buf_len > 0) { *((unsigned char *)(port->write_urb->transfer_buffer)) = (unsigned char)DIGI_CMD_SEND_DATA; *((unsigned char *)(port->write_urb->transfer_buffer)+1) = (unsigned char)priv->dp_out_buf_len; - - port->write_urb->transfer_buffer_length - = priv->dp_out_buf_len+2; + port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2; port->write_urb->dev = serial->dev; - - memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf, - priv->dp_out_buf_len ); - - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf, + priv->dp_out_buf_len); + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; } - } - /* wake up processes sleeping on writes immediately */ - digi_wakeup_write( port ); - + digi_wakeup_write(port); /* also queue up a wakeup at scheduler time, in case we */ /* lost the race in write_chan(). */ schedule_work(&priv->dp_wakeup_work); - spin_unlock( &priv->dp_port_lock ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - + spin_unlock(&priv->dp_port_lock); + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } - -static int digi_write_room( struct usb_serial_port *port ) +static int digi_write_room(struct usb_serial_port *port) { int room; struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; + spin_lock_irqsave(&priv->dp_port_lock, flags); - spin_lock_irqsave( &priv->dp_port_lock, flags ); - - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) + if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) room = 0; else room = port->bulk_out_size - 2 - priv->dp_out_buf_len; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - -dbg( "digi_write_room: port=%d, room=%d", priv->dp_port_num, room ); - return( room ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + dbg("digi_write_room: port=%d, room=%d", priv->dp_port_num, room); + return room; } - -static int digi_chars_in_buffer( struct usb_serial_port *port ) +static int digi_chars_in_buffer(struct usb_serial_port *port) { struct digi_port *priv = usb_get_serial_port_data(port); - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) { -dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, port->bulk_out_size - 2 ); - /* return( port->bulk_out_size - 2 ); */ - return( 256 ); + if (port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use) { + dbg("digi_chars_in_buffer: port=%d, chars=%d", + priv->dp_port_num, port->bulk_out_size - 2); + /* return(port->bulk_out_size - 2); */ + return 256; } else { -dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, priv->dp_out_buf_len ); - return( priv->dp_out_buf_len ); + dbg("digi_chars_in_buffer: port=%d, chars=%d", + priv->dp_port_num, priv->dp_out_buf_len); + return priv->dp_out_buf_len; } } -static int digi_open( struct usb_serial_port *port, struct file *filp ) +static int digi_open(struct usb_serial_port *port, struct file *filp) { - int ret; unsigned char buf[32]; struct digi_port *priv = usb_get_serial_port_data(port); struct ktermios not_termios; unsigned long flags = 0; - -dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); + dbg("digi_open: TOP: port=%d, open_count=%d", + priv->dp_port_num, port->open_count); /* be sure the device is started up */ - if( digi_startup_device( port->serial ) != 0 ) - return( -ENXIO ); + if (digi_startup_device(port->serial) != 0) + return -ENXIO; - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* don't wait on a close in progress for non-blocking opens */ - if( priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return( -EAGAIN ); + if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return -EAGAIN; } /* wait for a close in progress to finish */ - while( priv->dp_in_close ) { + while(priv->dp_in_close) { cond_wait_interruptible_timeout_irqrestore( &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); /* read modem signals automatically whenever they change */ buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; @@ -1486,23 +1381,22 @@ dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_cou buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; buf[7] = 0; - if( (ret=digi_write_oob_command( port, buf, 8, 1 )) != 0 ) - dbg( "digi_open: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0) + dbg("digi_open: write oob failed, ret=%d", ret); /* set termios settings */ not_termios.c_cflag = ~port->tty->termios->c_cflag; not_termios.c_iflag = ~port->tty->termios->c_iflag; - digi_set_termios( port, ¬_termios ); + digi_set_termios(port, ¬_termios); /* set DTR and RTS */ - digi_set_modem_signals( port, TIOCM_DTR|TIOCM_RTS, 1 ); - - return( 0 ); + digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1); + return 0; } -static void digi_close( struct usb_serial_port *port, struct file *filp ) +static void digi_close(struct usb_serial_port *port, struct file *filp) { DEFINE_WAIT(wait); int ret; @@ -1511,40 +1405,37 @@ static void digi_close( struct usb_serial_port *port, struct file *filp ) struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; - -dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); - + dbg("digi_close: TOP: port=%d, open_count=%d", + priv->dp_port_num, port->open_count); /* if disconnected, just clear flags */ if (!usb_get_intfdata(port->serial->interface)) goto exit; /* do cleanup only after final close on this port */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_in_close = 1; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); /* tell line discipline to process only XON/XOFF */ tty->closing = 1; /* wait for output to drain */ - if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - tty_wait_until_sent( tty, DIGI_CLOSE_TIMEOUT ); - } + if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) + tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT); /* flush driver and line discipline buffers */ - if( tty->driver->flush_buffer ) - tty->driver->flush_buffer( tty ); + if (tty->driver->flush_buffer) + tty->driver->flush_buffer(tty); tty_ldisc_flush(tty); if (port->serial->dev) { /* wait for transmit idle */ - if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT ); + if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { + digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); } - /* drop DTR and RTS */ - digi_set_modem_signals( port, 0, 0 ); + digi_set_modem_signals(port, 0, 0); /* disable input flow control */ buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; @@ -1576,8 +1467,8 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; buf[19] = 0; - if( (ret=digi_write_oob_command( port, buf, 20, 0 )) != 0 ) - dbg( "digi_close: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0) + dbg("digi_close: write oob failed, ret=%d", ret); /* wait for final commands on oob port to complete */ prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE); @@ -1587,17 +1478,14 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co /* shutdown any outstanding bulk writes */ usb_kill_urb(port->write_urb); } - tty->closing = 0; - exit: - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; - wake_up_interruptible( &priv->dp_close_wait ); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - -dbg( "digi_close: done" ); + wake_up_interruptible(&priv->dp_close_wait); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + dbg("digi_close: done"); } @@ -1608,155 +1496,136 @@ dbg( "digi_close: done" ); * urbs initialized. Returns 0 if successful, non-zero error otherwise. */ -static int digi_startup_device( struct usb_serial *serial ) +static int digi_startup_device(struct usb_serial *serial) { - int i,ret = 0; struct digi_serial *serial_priv = usb_get_serial_data(serial); struct usb_serial_port *port; - /* be sure this happens exactly once */ - spin_lock( &serial_priv->ds_serial_lock ); - if( serial_priv->ds_device_started ) { - spin_unlock( &serial_priv->ds_serial_lock ); - return( 0 ); + spin_lock(&serial_priv->ds_serial_lock); + if (serial_priv->ds_device_started) { + spin_unlock(&serial_priv->ds_serial_lock); + return 0; } serial_priv->ds_device_started = 1; - spin_unlock( &serial_priv->ds_serial_lock ); + spin_unlock(&serial_priv->ds_serial_lock); /* start reading from each bulk in endpoint for the device */ /* set USB_DISABLE_SPD flag for write bulk urbs */ - for( i=0; i<serial->type->num_ports+1; i++ ) { - + for (i = 0; i < serial->type->num_ports + 1; i++) { port = serial->port[i]; - port->write_urb->dev = port->serial->dev; - - if( (ret=usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0 ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, i ); + if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) { + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, i); break; } - } - - return( ret ); - + return ret; } -static int digi_startup( struct usb_serial *serial ) +static int digi_startup(struct usb_serial *serial) { int i; struct digi_port *priv; struct digi_serial *serial_priv; - -dbg( "digi_startup: TOP" ); + dbg("digi_startup: TOP"); /* allocate the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ - for( i=0; i<serial->type->num_ports+1; i++ ) { - + for(i = 0; i < serial->type->num_ports + 1; i++) { /* allocate port private structure */ - priv = kmalloc( sizeof(struct digi_port), - GFP_KERNEL ); - if( priv == (struct digi_port *)0 ) { - while( --i >= 0 ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - return( 1 ); /* error */ + priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); + if (priv == NULL) { + while (--i >= 0) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ } /* initialize port private structure */ - spin_lock_init( &priv->dp_port_lock ); + spin_lock_init(&priv->dp_port_lock); priv->dp_port_num = i; priv->dp_out_buf_len = 0; priv->dp_write_urb_in_use = 0; priv->dp_modem_signals = 0; - init_waitqueue_head( &priv->dp_modem_change_wait ); + init_waitqueue_head(&priv->dp_modem_change_wait); priv->dp_transmit_idle = 0; - init_waitqueue_head( &priv->dp_transmit_idle_wait ); + init_waitqueue_head(&priv->dp_transmit_idle_wait); priv->dp_throttled = 0; priv->dp_throttle_restart = 0; - init_waitqueue_head( &priv->dp_flush_wait ); + init_waitqueue_head(&priv->dp_flush_wait); priv->dp_in_close = 0; - init_waitqueue_head( &priv->dp_close_wait ); + init_waitqueue_head(&priv->dp_close_wait); INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); priv->dp_port = serial->port[i]; - /* initialize write wait queue for this port */ - init_waitqueue_head( &serial->port[i]->write_wait ); + init_waitqueue_head(&serial->port[i]->write_wait); usb_set_serial_port_data(serial->port[i], priv); } /* allocate serial private structure */ - serial_priv = kmalloc( sizeof(struct digi_serial), - GFP_KERNEL ); - if( serial_priv == (struct digi_serial *)0 ) { - for( i=0; i<serial->type->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - return( 1 ); /* error */ + serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); + if (serial_priv == NULL) { + for (i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ } /* initialize serial private structure */ - spin_lock_init( &serial_priv->ds_serial_lock ); + spin_lock_init(&serial_priv->ds_serial_lock); serial_priv->ds_oob_port_num = serial->type->num_ports; serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; serial_priv->ds_device_started = 0; usb_set_serial_data(serial, serial_priv); - return( 0 ); - + return 0; } -static void digi_shutdown( struct usb_serial *serial ) +static void digi_shutdown(struct usb_serial *serial) { - int i; - - -dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() ); + dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); /* stop reads and writes on all ports */ - for( i=0; i<serial->type->num_ports+1; i++ ) { + for (i = 0; i < serial->type->num_ports + 1; i++) { usb_kill_urb(serial->port[i]->read_urb); usb_kill_urb(serial->port[i]->write_urb); } /* free the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ - for( i=0; i<serial->type->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - kfree( usb_get_serial_data(serial) ); + for(i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + kfree(usb_get_serial_data(serial)); } -static void digi_read_bulk_callback( struct urb *urb ) +static void digi_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct digi_port *priv; struct digi_serial *serial_priv; int ret; int status = urb->status; - -dbg( "digi_read_bulk_callback: TOP" ); + dbg("digi_read_bulk_callback: TOP"); /* port sanity check, do not resubmit if port is not valid */ - if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { + if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", __FUNCTION__, status); return; } - if( port->serial == NULL - || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) { + if (port->serial == NULL || + (serial_priv=usb_get_serial_data(port->serial)) == NULL) { err("%s: serial is bad or serial->private is NULL, status=%d", - __FUNCTION__, status); + __FUNCTION__, status); return; } @@ -1768,24 +1637,23 @@ dbg( "digi_read_bulk_callback: TOP" ); } /* handle oob or inb callback, do not resubmit if error */ - if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { - if( digi_read_oob_callback( urb ) != 0 ) + if (priv->dp_port_num == serial_priv->ds_oob_port_num) { + if (digi_read_oob_callback(urb) != 0) return; } else { - if( digi_read_inb_callback( urb ) != 0 ) + if (digi_read_inb_callback(urb) != 0) return; } /* continue read */ urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(urb, GFP_ATOMIC)) != 0 ) { - err("%s: failed resubmitting urb, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); + if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { + err("%s: failed resubmitting urb, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } } - /* * Digi Read INB Callback * @@ -1796,7 +1664,7 @@ dbg( "digi_read_bulk_callback: TOP" ); * throttled, and -1 if the sanity checks failed. */ -static int digi_read_inb_callback( struct urb *urb ) +static int digi_read_inb_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1812,72 +1680,67 @@ static int digi_read_inb_callback( struct urb *urb ) /* do not process callbacks on closed ports */ /* but do continue the read chain */ - if( port->open_count == 0 ) - return( 0 ); + if (port->open_count == 0) + return 0; /* short/multiple packet check */ - if( urb->actual_length != len + 2 ) { - err("%s: INCOMPLETE OR MULTIPLE PACKET, urb status=%d, " + if (urb->actual_length != len + 2) { + err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, " "port=%d, opcode=%d, len=%d, actual_length=%d, " - "port_status=%d", __FUNCTION__, status, priv->dp_port_num, + "status=%d", __FUNCTION__, status, priv->dp_port_num, opcode, len, urb->actual_length, port_status); - return( -1 ); + return -1; } - spin_lock( &priv->dp_port_lock ); + spin_lock(&priv->dp_port_lock); /* check for throttle; if set, do not resubmit read urb */ /* indicate the read chain needs to be restarted on unthrottle */ throttled = priv->dp_throttled; - if( throttled ) + if (throttled) priv->dp_throttle_restart = 1; /* receive data */ - if( opcode == DIGI_CMD_RECEIVE_DATA ) { - + if (opcode == DIGI_CMD_RECEIVE_DATA) { /* get flag from port_status */ flag = 0; /* overrun is special, not associated with a char */ - if (port_status & DIGI_OVERRUN_ERROR) { - tty_insert_flip_char( tty, 0, TTY_OVERRUN ); - } + if (port_status & DIGI_OVERRUN_ERROR) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); /* break takes precedence over parity, */ /* which takes precedence over framing errors */ - if (port_status & DIGI_BREAK_ERROR) { + if (port_status & DIGI_BREAK_ERROR) flag = TTY_BREAK; - } else if (port_status & DIGI_PARITY_ERROR) { + else if (port_status & DIGI_PARITY_ERROR) flag = TTY_PARITY; - } else if (port_status & DIGI_FRAMING_ERROR) { + else if (port_status & DIGI_FRAMING_ERROR) flag = TTY_FRAME; - } /* data length is len-1 (one byte of len is port_status) */ --len; len = tty_buffer_request_room(tty, len); - if( len > 0 ) { + if (len > 0) { /* Hot path */ - if(flag == TTY_NORMAL) + if (flag == TTY_NORMAL) tty_insert_flip_string(tty, data, len); else { for(i = 0; i < len; i++) tty_insert_flip_char(tty, data[i], flag); } - tty_flip_buffer_push( tty ); + tty_flip_buffer_push(tty); } } + spin_unlock(&priv->dp_port_lock); - spin_unlock( &priv->dp_port_lock ); - - if( opcode == DIGI_CMD_RECEIVE_DISABLE ) { - dbg("%s: got RECEIVE_DISABLE", __FUNCTION__ ); - } else if( opcode != DIGI_CMD_RECEIVE_DATA ) { - dbg("%s: unknown opcode: %d", __FUNCTION__, opcode ); - } + if (opcode == DIGI_CMD_RECEIVE_DISABLE) + dbg("%s: got RECEIVE_DISABLE", __FUNCTION__); + else if (opcode != DIGI_CMD_RECEIVE_DATA) + dbg("%s: unknown opcode: %d", __FUNCTION__, opcode); - return( throttled ? 1 : 0 ); + return(throttled ? 1 : 0); } @@ -1891,7 +1754,7 @@ static int digi_read_inb_callback( struct urb *urb ) * -1 if the sanity checks failed. */ -static int digi_read_oob_callback( struct urb *urb ) +static int digi_read_oob_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1900,87 +1763,75 @@ static int digi_read_oob_callback( struct urb *urb ) int opcode, line, status, val; int i; - -dbg( "digi_read_oob_callback: port=%d, len=%d", priv->dp_port_num, -urb->actual_length ); + dbg("digi_read_oob_callback: port=%d, len=%d", + priv->dp_port_num, urb->actual_length); /* handle each oob command */ - for( i=0; i<urb->actual_length-3; ) { - + for(i = 0; i < urb->actual_length - 3;) { opcode = ((unsigned char *)urb->transfer_buffer)[i++]; line = ((unsigned char *)urb->transfer_buffer)[i++]; status = ((unsigned char *)urb->transfer_buffer)[i++]; val = ((unsigned char *)urb->transfer_buffer)[i++]; -dbg( "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", -opcode, line, status, val ); + dbg("digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", + opcode, line, status, val); - if( status != 0 || line >= serial->type->num_ports ) + if (status != 0 || line >= serial->type->num_ports) continue; port = serial->port[line]; - if ((priv=usb_get_serial_port_data(port)) == NULL ) + if ((priv=usb_get_serial_port_data(port)) == NULL) return -1; - if( opcode == DIGI_CMD_READ_INPUT_SIGNALS ) { - - spin_lock( &priv->dp_port_lock ); - + if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { + spin_lock(&priv->dp_port_lock); /* convert from digi flags to termiox flags */ - if( val & DIGI_READ_INPUT_SIGNALS_CTS ) { + if (val & DIGI_READ_INPUT_SIGNALS_CTS) { priv->dp_modem_signals |= TIOCM_CTS; /* port must be open to use tty struct */ - if( port->open_count - && port->tty->termios->c_cflag & CRTSCTS ) { + if (port->open_count + && port->tty->termios->c_cflag & CRTSCTS) { port->tty->hw_stopped = 0; - digi_wakeup_write( port ); + digi_wakeup_write(port); } } else { priv->dp_modem_signals &= ~TIOCM_CTS; /* port must be open to use tty struct */ - if( port->open_count - && port->tty->termios->c_cflag & CRTSCTS ) { + if (port->open_count + && port->tty->termios->c_cflag & CRTSCTS) { port->tty->hw_stopped = 1; } } - if( val & DIGI_READ_INPUT_SIGNALS_DSR ) + if (val & DIGI_READ_INPUT_SIGNALS_DSR) priv->dp_modem_signals |= TIOCM_DSR; else priv->dp_modem_signals &= ~TIOCM_DSR; - if( val & DIGI_READ_INPUT_SIGNALS_RI ) + if (val & DIGI_READ_INPUT_SIGNALS_RI) priv->dp_modem_signals |= TIOCM_RI; else priv->dp_modem_signals &= ~TIOCM_RI; - if( val & DIGI_READ_INPUT_SIGNALS_DCD ) + if (val & DIGI_READ_INPUT_SIGNALS_DCD) priv->dp_modem_signals |= TIOCM_CD; else priv->dp_modem_signals &= ~TIOCM_CD; - wake_up_interruptible( &priv->dp_modem_change_wait ); - spin_unlock( &priv->dp_port_lock ); - - } else if( opcode == DIGI_CMD_TRANSMIT_IDLE ) { - - spin_lock( &priv->dp_port_lock ); + wake_up_interruptible(&priv->dp_modem_change_wait); + spin_unlock(&priv->dp_port_lock); + } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { + spin_lock(&priv->dp_port_lock); priv->dp_transmit_idle = 1; - wake_up_interruptible( &priv->dp_transmit_idle_wait ); - spin_unlock( &priv->dp_port_lock ); - - } else if( opcode == DIGI_CMD_IFLUSH_FIFO ) { - - wake_up_interruptible( &priv->dp_flush_wait ); - + wake_up_interruptible(&priv->dp_transmit_idle_wait); + spin_unlock(&priv->dp_port_lock); + } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { + wake_up_interruptible(&priv->dp_flush_wait); } - } - - return( 0 ); + return 0; } - -static int __init digi_init (void) +static int __init digi_init(void) { int retval; retval = usb_serial_register(&digi_acceleport_2_device); @@ -2002,12 +1853,11 @@ failed_acceleport_2_device: return retval; } - static void __exit digi_exit (void) { - usb_deregister (&digi_driver); - usb_serial_deregister (&digi_acceleport_2_device); - usb_serial_deregister (&digi_acceleport_4_device); + usb_deregister(&digi_driver); + usb_serial_deregister(&digi_acceleport_2_device); + usb_serial_deregister(&digi_acceleport_4_device); } @@ -2015,8 +1865,8 @@ module_init(digi_init); module_exit(digi_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dd42f57089f..2ecb1d2a034 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2366,9 +2366,8 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa int status; unsigned char number = edge_port->port->number - edge_port->port->serial->minor; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) { dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", edge_port->port->number, baudRate); return 0; @@ -2461,18 +2460,16 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && - (regNum == MCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && + regNum == MCR) { dbg("SendCmdWriteUartReg - Not writing to MCR Register"); return 0; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && - (regNum == LCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteLCR && + regNum == LCR) { dbg ("SendCmdWriteUartReg - Not writing to LCR Register"); return 0; } diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2a3fabcf518..e08c9bb403d 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -184,21 +184,21 @@ struct mct_u232_private { * we do not know how to support. We ignore them for the moment. * XXX Rate-limit the error message, it's user triggerable. */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) +static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value) { if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { switch (value) { - case B300: return 0x01; - case B600: return 0x02; /* this one not tested */ - case B1200: return 0x03; - case B2400: return 0x04; - case B4800: return 0x06; - case B9600: return 0x08; - case B19200: return 0x09; - case B38400: return 0x0a; - case B57600: return 0x0b; - case B115200: return 0x0c; + case 300: return 0x01; + case 600: return 0x02; /* this one not tested */ + case 1200: return 0x03; + case 2400: return 0x04; + case 4800: return 0x06; + case 9600: return 0x08; + case 19200: return 0x09; + case 38400: return 0x0a; + case 57600: return 0x0b; + case 115200: return 0x0c; default: err("MCT USB-RS232: unsupported baudrate request 0x%x," " using default of B9600", value); @@ -206,27 +206,27 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) } } else { switch (value) { - case B300: value = 300; break; - case B600: value = 600; break; - case B1200: value = 1200; break; - case B2400: value = 2400; break; - case B4800: value = 4800; break; - case B9600: value = 9600; break; - case B19200: value = 19200; break; - case B38400: value = 38400; break; - case B57600: value = 57600; break; - case B115200: value = 115200; break; - default: - err("MCT USB-RS232: unsupported baudrate request 0x%x," - " using default of B9600", value); - value = 9600; + case 300: break; + case 600: break; + case 1200: break; + case 2400: break; + case 4800: break; + case 9600: break; + case 19200: break; + case 38400: break; + case 57600: break; + case 115200: break; + default: + err("MCT USB-RS232: unsupported baudrate request 0x%x," + " using default of B9600", value); + value = 9600; } return 115200/value; } } static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port, - int value) + speed_t value) { __le32 divisor; int rc; @@ -634,7 +634,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port, mct_u232_set_modem_ctrl(serial, control_state); } - mct_u232_set_baud_rate(serial, port, cflag & CBAUD); + mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty)); if ((cflag & CBAUD) == B0 ) { dbg("%s: baud is B0", __FUNCTION__); diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index a61bac8f224..aae10c8174d 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h @@ -79,7 +79,7 @@ * and "Intel solution". They are the regular MCT and "Sitecom" for us. * This is pointless to document in the header, see the code for the bits. */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value); +static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value); /* * Line Control Register (LCR) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0794ccdebfd..0bb8de4cc52 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -45,7 +45,7 @@ enum devicetype { DEVICE_INSTALLER = 2, }; -int sierra_set_power_state(struct usb_device *udev, __u16 swiState) +static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) { int result; dev_dbg(&udev->dev, "%s", "SET POWER STATE"); @@ -60,7 +60,7 @@ int sierra_set_power_state(struct usb_device *udev, __u16 swiState) return result; } -int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) +static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) { int result; dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); @@ -75,7 +75,8 @@ int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) return result; } -int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id) +static int sierra_probe(struct usb_interface *iface, + const struct usb_device_id *id) { int result; struct usb_device *udev; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a3665659d13..9bf01a5efc8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -60,19 +60,19 @@ static struct usb_driver usb_serial_driver = { static int debug; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ -static spinlock_t table_lock; +static DEFINE_MUTEX(table_lock); static LIST_HEAD(usb_serial_driver_list); struct usb_serial *usb_serial_get_by_index(unsigned index) { struct usb_serial *serial; - spin_lock(&table_lock); + mutex_lock(&table_lock); serial = serial_table[index]; if (serial) kref_get(&serial->kref); - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return serial; } @@ -84,7 +84,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po dbg("%s %d", __FUNCTION__, num_ports); *minor = 0; - spin_lock(&table_lock); + mutex_lock(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) continue; @@ -106,10 +106,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po serial_table[i] = serial; serial->port[j++]->number = i; } - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return serial; } - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return NULL; } @@ -172,9 +172,9 @@ static void destroy_serial(struct kref *kref) void usb_serial_put(struct usb_serial *serial) { - spin_lock(&table_lock); + mutex_lock(&table_lock); kref_put(&serial->kref, destroy_serial); - spin_unlock(&table_lock); + mutex_unlock(&table_lock); } /***************************************************************************** @@ -1077,16 +1077,17 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) struct usb_serial_port *port; int i, r = 0; - if (serial) { - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port) - kill_traffic(port); - } + if (!serial) /* device has been disconnected */ + return 0; + + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (port) + kill_traffic(port); } if (serial->type->suspend) - serial->type->suspend(serial, message); + r = serial->type->suspend(serial, message); return r; } @@ -1128,7 +1129,6 @@ static int __init usb_serial_init(void) return -ENOMEM; /* Initialize our global data */ - spin_lock_init(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { serial_table[i] = NULL; } diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a624e72f81d..d8d008d4294 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -320,6 +320,13 @@ UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */ +UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, + "NIKON", + "NIKON DSC D50", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Andreas Bockhold <andreas@bockionline.de> */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -1357,6 +1364,20 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Jeremy Katz <katzj@redhat.com>: + * The Blackberry Pearl can run in two modes; a usb-storage only mode + * and a mode that allows access via mass storage and to its database. + * The berry_charge module will set the device to dual mode and thus we + * should ignore its native mode if that module is built + */ +#ifdef CONFIG_USB_BERRY_CHARGE +UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, + "RIM", + "Blackberry Pearl", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), +#endif + /* Reported by Michael Stattmann <michael@stattmann.com> */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", |