Date: Mon, 19 Jan 2009 19:50:12 -0800 From: Sean Bruno <sean.bruno@dsl-only.net> To: freebsd-firewire <freebsd-firewire@FreeBSD.org> Cc: scottl@freebsd.org Subject: Firewire patch Message-ID: <1232423412.8966.2.camel@localhost.localdomain>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Sorry it's taking me so long to wrap my brain around this code folks.
Here is a small-ish patch I'd like to get comitted soon. This removes
the filter implementation of the bus reset interrupt. It moves some
malloc's into a more appropriate area and fixes a potential deadlock in
SBP.
Take a peak and give it a spin on stable/7
Sean
[-- Attachment #2 --]
Index: fwohci_pci.c
===================================================================
--- fwohci_pci.c (revision 187454)
+++ fwohci_pci.c (working copy)
@@ -31,7 +31,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/7/sys/dev/firewire/fwohci_pci.c 170374 2007-06-06 14:31:36Z simokawa $
*/
#define BOUNCE_BUFFER_TEST 0
@@ -337,11 +337,8 @@
err = bus_setup_intr(self, sc->irq_res,
INTR_TYPE_NET | INTR_MPSAFE,
-#if FWOHCI_INTFILT
- fwohci_filt, NULL, sc, &sc->ih);
-#else
NULL, (driver_intr_t *) fwohci_intr, sc, &sc->ih);
-#endif
+
#if defined(__DragonFly__) || __FreeBSD_version < 500000
/* XXX splcam() should mask this irq for sbp.c*/
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_CAM,
Index: firewire.c
===================================================================
--- firewire.c (revision 187454)
+++ firewire.c (working copy)
@@ -31,7 +31,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/7/sys/dev/firewire/firewire.c 171513 2007-07-20 03:42:57Z simokawa $
*
*/
@@ -429,6 +429,16 @@
fwdev_makedev(sc);
+ fc->crom_src_buf = (struct crom_src_buf *)malloc(
+ sizeof(struct crom_src_buf),
+ M_FW, M_NOWAIT | M_ZERO);
+ fc->topology_map = (struct fw_topology_map *)malloc(
+ sizeof(struct fw_topology_map),
+ M_FW, M_NOWAIT | M_ZERO);
+ fc->speed_map = (struct fw_speed_map *)malloc(
+ sizeof(struct fw_speed_map),
+ M_FW, M_NOWAIT | M_ZERO);
+
mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
CALLOUT_INIT(&fc->timeout_callout);
@@ -450,7 +460,9 @@
bus_generic_attach(dev);
/* bus_reset */
+ FW_GLOCK(fc);
fw_busreset(fc, FWBUSNOTREADY);
+ FW_GUNLOCK(fc);
fc->ibr(fc);
return 0;
@@ -638,11 +650,6 @@
{
struct crom_src *src;
- fc->crom_src_buf = (struct crom_src_buf *)
- malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO);
- if (fc->crom_src_buf == NULL)
- return;
-
src = &fc->crom_src_buf->src;
bzero(src, sizeof(struct crom_src));
@@ -659,7 +666,7 @@
src->businfo.cyc_clk_acc = 100;
src->businfo.max_rec = fc->maxrec;
src->businfo.max_rom = MAXROM_4;
- src->businfo.generation = 1;
+ src->businfo.generation = 0;
src->businfo.link_spd = fc->speed;
src->businfo.eui64.hi = fc->eui.hi;
@@ -678,9 +685,6 @@
struct crom_src *src;
struct crom_chunk *root;
- if (fc->crom_src_buf == NULL)
- fw_init_crom(fc);
-
buf = fc->crom_src_buf;
src = fc->crom_src;
root = fc->crom_root;
@@ -711,18 +715,18 @@
struct firewire_dev_comm *fdc;
struct crom_src *src;
device_t *devlistp;
- void *newrom;
int i, devcnt;
- switch(fc->status){
- case FWBUSMGRELECT:
- callout_stop(&fc->bmr_callout);
- break;
- default:
- break;
- }
+ FW_GLOCK_ASSERT(fc);
+ if (fc->status == FWBUSMGRELECT)
+ callout_stop(&fc->bmr_callout);
+
fc->status = new_status;
fw_reset_csr(fc);
+
+ if (fc->status == FWBUSNOTREADY)
+ fw_init_crom(fc);
+
fw_reset_crom(fc);
if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) {
@@ -735,19 +739,19 @@
free(devlistp, M_TEMP);
}
- newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
src = &fc->crom_src_buf->src;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
- if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
- /* bump generation and reload */
- src->businfo.generation ++;
- /* generation must be between 0x2 and 0xF */
- if (src->businfo.generation < 2)
- src->businfo.generation ++;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
- bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
- }
- free(newrom, M_FW);
+ /*
+ * If the old config rom needs to be overwritten,
+ * bump the businfo.generation indicator to
+ * indicate that we need to be reprobed
+ */
+ if (bcmp(src, fc->config_rom, CROMSIZE) != 0) {
+ /* generation is a 2 bit field */
+ /* valid values are only from 0 - 3 */
+ src->businfo.generation = 1;
+ bcopy(src, (void *)fc->config_rom, CROMSIZE);
+ } else
+ src->businfo.generation = 0;
}
/* Call once after reboot */
@@ -803,13 +807,6 @@
fc->ir[i]->maxq = FWMAXQUEUE;
fc->it[i]->maxq = FWMAXQUEUE;
}
-/* Initialize csr registers */
- fc->topology_map = (struct fw_topology_map *)malloc(
- sizeof(struct fw_topology_map),
- M_FW, M_NOWAIT | M_ZERO);
- fc->speed_map = (struct fw_speed_map *)malloc(
- sizeof(struct fw_speed_map),
- M_FW, M_NOWAIT | M_ZERO);
CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
CSRARC(fc, TOPO_MAP + 4) = 1;
CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
@@ -1555,7 +1552,7 @@
/* unchanged ? */
if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
if (firewire_debug)
- printf("node%d: crom unchanged\n", node);
+ device_printf(fc->dev, "node(%d): crom unchanged\n", node);
return (0);
}
Index: fwohci.c
===================================================================
--- fwohci.c (revision 187454)
+++ fwohci.c (working copy)
@@ -31,7 +31,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/7/sys/dev/firewire/fwohci.c 170427 2007-06-08 09:04:30Z simokawa $
*
*/
@@ -1003,7 +1003,7 @@
if (maxdesc < db_tr->dbcnt) {
maxdesc = db_tr->dbcnt;
if (firewire_debug)
- device_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc);
+ device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
}
/* last db */
LAST_DB(db_tr, db);
@@ -1843,6 +1843,7 @@
struct firewire_comm *fc = (struct firewire_comm *)sc;
uint32_t node_id, plen;
+ FW_GLOCK_ASSERT(fc);
if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
fc->status = FWBUSRESET;
/* Disable bus reset interrupt until sid recv. */
@@ -1885,8 +1886,8 @@
plen = OREAD(sc, OHCI_SID_CNT);
fc->nodeid = node_id & 0x3f;
- device_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
- node_id, (plen >> 16) & 0xff);
+ device_printf(fc->dev, "node_id=0x%08x, SelfID Count=%d, ",
+ fc->nodeid, (plen >> 16) & 0xff);
if (!(node_id & OHCI_NODE_VALID)) {
printf("Bus reset failure\n");
goto sidout;
@@ -1997,9 +1998,11 @@
{
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
+ FW_GLOCK(&sc->fc);
fw_busreset(&sc->fc, FWBUSRESET);
OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
+ FW_GUNLOCK(&sc->fc);
}
static void
@@ -2062,6 +2065,7 @@
{
uint32_t stat, irstat, itstat;
+ FW_GLOCK_ASSERT(&sc->fc);
stat = OREAD(sc, FWOHCI_INTSTAT);
if (stat == 0xffffffff) {
device_printf(sc->fc.dev,
@@ -2091,29 +2095,23 @@
return (FILTER_HANDLED);
}
-int
-fwohci_filt(void *arg)
+void
+fwohci_intr(void *arg)
{
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
- if (!(sc->intmask & OHCI_INT_EN)) {
- /* polling mode */
- return (FILTER_STRAY);
- }
- return (fwohci_check_stat(sc));
+ FW_GLOCK(&sc->fc);
+ fwohci_check_stat(sc);
+ FW_GUNLOCK(&sc->fc);
}
void
-fwohci_intr(void *arg)
-{
- fwohci_filt(arg);
-}
-
-void
fwohci_poll(struct firewire_comm *fc, int quick, int count)
{
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ FW_GLOCK(fc);
fwohci_check_stat(sc);
+ FW_GUNLOCK(fc);
}
static void
@@ -2471,6 +2469,7 @@
* Make sure our cached values from the config rom are
* initialised.
*/
+ FW_GLOCK(fc);
OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
@@ -2487,6 +2486,7 @@
fun |= FW_PHY_ISBR | FW_PHY_RHB;
fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
#endif
+ FW_GUNLOCK(fc);
}
void
Index: sbp.c
===================================================================
--- sbp.c (revision 187454)
+++ sbp.c (working copy)
@@ -31,7 +31,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/7/sys/dev/firewire/sbp.c 170872 2007-06-17 05:55:54Z scottl $
*
*/
@@ -1255,11 +1255,18 @@
htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
+ /*
+ * sbp_xfer_free() will attempt to acquire
+ * the SBP lock on entrance. Also, this removes
+ * a LOR between the firewire layer and sbp
+ */
+ SBP_UNLOCK(sdev->target->sbp);
if(fw_asyreq(xfer->fc, -1, xfer) != 0){
sbp_xfer_free(xfer);
ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ocb->ccb);
}
+ SBP_LOCK(sdev->target->sbp);
}
static void
Index: fwohcivar.h
===================================================================
--- fwohcivar.h (revision 187454)
+++ fwohcivar.h (working copy)
@@ -31,18 +31,12 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/7/sys/dev/firewire/fwohcivar.h 170374 2007-06-06 14:31:36Z simokawa $
*
*/
#include <sys/taskqueue.h>
-#if defined(__DragonFly__) || __FreeBSD_version < 700043
-#define FWOHCI_INTFILT 0
-#else
-#define FWOHCI_INTFILT 1
-#endif
-
typedef struct fwohci_softc {
struct firewire_comm fc;
bus_space_tag_t bst;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1232423412.8966.2.camel>
