kern/172833: tws driver update from LSI
Charles O'Donnell
cao at bus.net
Wed Oct 17 18:20:01 UTC 2012
>Number: 172833
>Category: kern
>Synopsis: tws driver update from LSI
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Oct 17 18:20:00 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Charles O'Donnell
>Release: 8.3R
>Organization:
>Environment:
FreeBSD mrt.odonnellpdc.com 8.3-RELEASE-p4 FreeBSD 8.3-RELEASE-p4 #0: Fri Oct 5 18:21:36 EDT 2012 root at mrt.odonnellpdc.com:/usr/src/sys/amd64/compile/GENERIC amd64
>Description:
Kernel panic in tws with 3ware 9750.
>How-To-Repeat:
Panic seemed random, but LSI provided me with an information gathering script "LSIget" which will trigger the panic reliably during one of the probe phases.
>Fix:
LSI provided a new driver not on their website (tws driver 005) that fixed the problem.
8.3R contains tws driver 003.
I can supply the diffs for the new driver, or the new driver package in its entirety. I am not sure if the new driver is beta or production, but would like to make it available to whomever is maintaining the tws driver in the FreeBSD source tree, and I am willing to test any modifications.
Patch attached with submission follows:
diff tws.dist/tws.c tws/tws.c
33c33,35
< */
---
> *
> * $FreeBSD: src/sys/dev/tws/tws.c,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
35,36d36
< #include <sys/cdefs.h>
< __FBSDID("$FreeBSD: src/sys/dev/tws/tws.c,v 1.1.4.5.2.1 2012/03/03 06:15:13 kensmith Exp $");
175c175
< return(BUS_PROBE_DEFAULT);
---
> return(0);
407a408,409
> if (sc->ioctl_data_mem)
> bus_dmamem_free(sc->data_tag, sc->ioctl_data_mem, sc->ioctl_data_map);
611a614,618
> if (bus_dmamem_alloc(sc->data_tag, (void **)&sc->ioctl_data_mem,
> (BUS_DMA_NOWAIT | BUS_DMA_ZERO), &sc->ioctl_data_map)) {
> device_printf(sc->tws_dev, "Cannot allocate ioctl data mem\n");
> return(ENOMEM);
> }
688d694
< mtx_unlock(&sc->q_lock);
886c892,894
< DEVMETHOD_END
---
> DEVMETHOD(bus_print_child, bus_generic_print_child),
> DEVMETHOD(bus_driver_added, bus_generic_driver_added),
> { 0, 0 }
diff tws.dist/tws.h tws/tws.h
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws.h,v 1.1.4.3.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws.h,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
68c68
< #define TWS_DRIVER_VERSION_STRING "10.80.00.003"
---
> #define TWS_DRIVER_VERSION_STRING "10.80.00.005"
208d207
< #ifndef __bool_true_false_are_defined
210,212d208
< #else
< #define boolean bool
< #endif
250c246
< int chan; /* wait channel */
---
> void *chan; /* IOCTL req wait channel */
262a259,260
> void *ioctl_data_mem; /* ioctl dmable memory */
> bus_dmamap_t ioctl_data_map; /* ioctl data map */
diff tws.dist/tws_cam.c tws/tws_cam.c
27c27
< * $FreeBSD: src/sys/dev/tws/tws_cam.c,v 1.1.4.2.2.1 2012/03/03 06:15:13 kensmith Exp $
---
> * $FreeBSD: src/sys/dev/tws/tws_cam.c,v 1.3 2007/05/09 04:16:32 mrangana Exp $
972a973
> error = 0; // EINPROGRESS is not a fatal error.
991a993,996
> if ( error ) {
> TWS_TRACE(sc, "SOMETHING BAD HAPPENED! error = %d\n", error, 0);
> }
>
1013c1018
< ((req->sc->is64bit && !tws_use_32bit_sgls) ? 4 :2 );
---
> ((req->sc->is64bit && !tws_use_32bit_sgls) ? 4 : 2 );
1018c1023
< (void *)req->cmd_pkt->cmd.pkt_a.sg_list, sgls);
---
> (void *)&(req->cmd_pkt->cmd.pkt_a.sg_list), sgls);
1321,1324c1326
< if ( sc->chan ) {
< sc->chan = 0;
< wakeup_one((void *)&sc->chan);
< }
---
> wakeup_one(sc->chan);
diff tws.dist/tws_hdm.c tws/tws_hdm.c
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_hdm.c,v 1.1.4.2.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_hdm.c,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
diff tws.dist/tws_hdm.h tws/tws_hdm.h
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_hdm.h,v 1.1.4.2.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_hdm.h,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
177c177
< #define TWS_FW_CMD_ATA_PASSTHROUGH 0x11
---
> #define TWS_FW_CMD_ATA_PASSTHROUGH 0x11 // This is really a PASSTHROUGH for both ATA and SCSI commands.
diff tws.dist/tws_services.c tws/tws_services.c
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_services.c,v 1.1.4.3.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_cam.c,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
56c56
< static struct error_desc array[] = {
---
> struct error_desc array[] = {
diff tws.dist/tws_services.h tws/tws_services.h
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_services.h,v 1.1.4.3.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_services.h,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
104d103
< #if 0
106d104
< #endif
116a115
> extern struct error_desc array[];
diff tws.dist/tws_user.c tws/tws_user.c
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_user.c,v 1.1.4.2.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_user.c,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
96a97
>
100a102,104
> //==============================================================================================
> // Get a command
> //
104,106c108,109
< sc->chan = 1;
< error = tsleep((void *)&sc->chan, 0,
< "tws_sleep", TWS_IOCTL_TIMEOUT*hz);
---
> sc->chan = (void *)sc;
> error = tsleep(sc->chan, 0, "tws_sleep", TWS_IOCTL_TIMEOUT*hz);
110a114,117
> // Make sure we are still ready for new commands...
> if ( tws_get_state(sc) != TWS_ONLINE) {
> return(EBUSY);
> }
113c120
< }while(1);
---
> } while(1);
115c122
< req->length = ubuf->driver_pkt.buffer_length;
---
> req->length = (ubuf->driver_pkt.buffer_length + 511) & ~511;
118,129c125,130
< req->data = malloc(req->length, M_TWS, M_WAITOK | M_ZERO);
< if ( !req->data ) {
< TWS_TRACE_DEBUG(sc, "malloc failed", 0, req->request_id);
< req->state = TWS_REQ_STATE_FREE;
< ubuf->driver_pkt.os_status = ENOMEM;
< if ( sc->chan ) {
< sc->chan = 0;
< wakeup_one((void *)&sc->chan);
< }
< return(ENOMEM);
< }
< bzero(req->data, req->length);
---
> req->data = sc->ioctl_data_mem;
> req->dma_map = sc->ioctl_data_map;
>
> //==========================================================================================
> // Copy data in from user space
> //
131a133,136
>
> //==============================================================================================
> // Set command fields
> //
144d148
<
146a151,153
> //==============================================================================================
> // Send command to controller
> //
150c157,162
< goto out;
---
> goto out_data;
> }
>
> if ( req->state == TWS_REQ_STATE_COMPLETE ) {
> ubuf->driver_pkt.os_status = req->error_code;
> goto out_unmap;
153d164
< //==================================================================================================
161a173
> out_unmap:
169a182,184
> //==============================================================================================
> // Return command status to user space
> //
172,175d186
< if ( !error && req->length ) {
< error = copyout(req->data, ubuf->pdata, req->length);
< }
< //==================================================================================================
177,178c188,195
< out:
< free(req->data, M_TWS);
---
> out_data:
> if ( req->length ) {
> //==========================================================================================
> // Copy data out to user space
> //
> if ( !error )
> error = copyout(req->data, ubuf->pdata, ubuf->driver_pkt.buffer_length);
> }
185a203,205
> //==============================================================================================
> // Free command
> //
188,191c208,209
< if ( sc->chan && (tws_get_state(sc) == TWS_ONLINE) ) {
< sc->chan = 0;
< wakeup_one((void *)&sc->chan);
< }
---
> wakeup_one(sc->chan);
>
diff tws.dist/tws_user.h tws/tws_user.h
34,35c34,35
< * $FreeBSD: src/sys/dev/tws/tws_user.h,v 1.1.4.2.2.1 2012/03/03 06:15:13 kensmith Exp $
< */
---
> * $FreeBSD: src/sys/dev/tws/tws_user.h,v 1.3 2007/05/09 04:16:32 mrangana Exp $
> */
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list