Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Oct 2012 18:17:04 GMT
From:      "Charles O'Donnell" <cao@bus.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/172833: tws driver update from LSI
Message-ID:  <201210171817.q9HIH4OX072757@red.freebsd.org>
Resent-Message-ID: <201210171820.q9HIK1HK075946@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210171817.q9HIH4OX072757>