Deleted Added
full compact
tw_osl_cam.c (170872) tw_osl_cam.c (172496)
1/*
2 * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
3 * Copyright (c) 2004-05 Vinod Kashyap.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*
2 * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
3 * Copyright (c) 2004-05 Vinod Kashyap.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/twa/tw_osl_cam.c 170872 2007-06-17 05:55:54Z scottl $
27 * $FreeBSD: head/sys/dev/twa/tw_osl_cam.c 172496 2007-10-09 17:43:57Z scottl $
28 */
29
30/*
31 * AMCC'S 3ware driver for 9000 series storage controllers.
32 *
33 * Author: Vinod Kashyap
34 * Modifications by: Adam Radford
28 */
29
30/*
31 * AMCC'S 3ware driver for 9000 series storage controllers.
32 *
33 * Author: Vinod Kashyap
34 * Modifications by: Adam Radford
35 * Modifications by: Manjunath Ranganathaiah
35 */
36
37
38/*
39 * FreeBSD CAM related functions.
40 */
41
42

--- 6 unchanged lines hidden (view full) ---

49#include <cam/cam_debug.h>
50#include <cam/cam_periph.h>
51
52#include <cam/scsi/scsi_all.h>
53#include <cam/scsi/scsi_message.h>
54
55static TW_VOID twa_action(struct cam_sim *sim, union ccb *ccb);
56static TW_VOID twa_poll(struct cam_sim *sim);
36 */
37
38
39/*
40 * FreeBSD CAM related functions.
41 */
42
43

--- 6 unchanged lines hidden (view full) ---

50#include <cam/cam_debug.h>
51#include <cam/cam_periph.h>
52
53#include <cam/scsi/scsi_all.h>
54#include <cam/scsi/scsi_message.h>
55
56static TW_VOID twa_action(struct cam_sim *sim, union ccb *ccb);
57static TW_VOID twa_poll(struct cam_sim *sim);
57static TW_VOID twa_async(TW_VOID *callback_arg, TW_UINT32 code,
58 struct cam_path *path, TW_VOID *arg);
59static TW_VOID twa_timeout(TW_VOID *arg);
60static TW_VOID twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb);
61
62static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
63 union ccb *ccb);
64
65
66

--- 5 unchanged lines hidden (view full) ---

72 * Output: None
73 * Return value: 0 -- success
74 * non-zero-- failure
75 */
76TW_INT32
77tw_osli_cam_attach(struct twa_softc *sc)
78{
79 struct cam_devq *devq;
58static TW_VOID twa_timeout(TW_VOID *arg);
59static TW_VOID twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb);
60
61static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
62 union ccb *ccb);
63
64
65

--- 5 unchanged lines hidden (view full) ---

71 * Output: None
72 * Return value: 0 -- success
73 * non-zero-- failure
74 */
75TW_INT32
76tw_osli_cam_attach(struct twa_softc *sc)
77{
78 struct cam_devq *devq;
80 struct ccb_setasync csa;
81 TW_INT32 error;
82
83 tw_osli_dbg_dprintf(3, sc, "entered");
84
85 /*
86 * Create the device queue for our SIM.
87 */
88 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {

--- 9 unchanged lines hidden (view full) ---

98 /*
99 * Create a SIM entry. Though we can support TW_OSLI_MAX_NUM_IOS
100 * simultaneous requests, we claim to be able to handle only
101 * (TW_OSLI_MAX_NUM_IOS - 1), so that we always have a request
102 * packet available to service ioctls.
103 */
104 tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc");
105 sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc,
79 TW_INT32 error;
80
81 tw_osli_dbg_dprintf(3, sc, "entered");
82
83 /*
84 * Create the device queue for our SIM.
85 */
86 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {

--- 9 unchanged lines hidden (view full) ---

96 /*
97 * Create a SIM entry. Though we can support TW_OSLI_MAX_NUM_IOS
98 * simultaneous requests, we claim to be able to handle only
99 * (TW_OSLI_MAX_NUM_IOS - 1), so that we always have a request
100 * packet available to service ioctls.
101 */
102 tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc");
103 sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc,
106 device_get_unit(sc->bus_dev), &Giant,
104 device_get_unit(sc->bus_dev), sc->sim_lock,
107 TW_OSLI_MAX_NUM_IOS - 1, 1, devq);
108 if (sc->sim == NULL) {
109 cam_simq_free(devq);
110 tw_osli_printf(sc, "error = %d",
111 TW_CL_SEVERITY_ERROR_STRING,
112 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
113 0x2101,
114 "Failed to create a SIM entry",
115 ENOMEM);
116 return(ENOMEM);
117 }
118
119 /*
120 * Register the bus.
121 */
122 tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register");
105 TW_OSLI_MAX_NUM_IOS - 1, 1, devq);
106 if (sc->sim == NULL) {
107 cam_simq_free(devq);
108 tw_osli_printf(sc, "error = %d",
109 TW_CL_SEVERITY_ERROR_STRING,
110 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
111 0x2101,
112 "Failed to create a SIM entry",
113 ENOMEM);
114 return(ENOMEM);
115 }
116
117 /*
118 * Register the bus.
119 */
120 tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register");
123 mtx_lock(&Giant);
121 mtx_lock(sc->sim_lock);
124 if (xpt_bus_register(sc->sim, sc->bus_dev, 0) != CAM_SUCCESS) {
125 cam_sim_free(sc->sim, TRUE);
126 sc->sim = NULL; /* so cam_detach will not try to free it */
127 tw_osli_printf(sc, "error = %d",
128 TW_CL_SEVERITY_ERROR_STRING,
129 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
130 0x2102,
131 "Failed to register the bus",
132 ENXIO);
122 if (xpt_bus_register(sc->sim, sc->bus_dev, 0) != CAM_SUCCESS) {
123 cam_sim_free(sc->sim, TRUE);
124 sc->sim = NULL; /* so cam_detach will not try to free it */
125 tw_osli_printf(sc, "error = %d",
126 TW_CL_SEVERITY_ERROR_STRING,
127 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
128 0x2102,
129 "Failed to register the bus",
130 ENXIO);
133 mtx_unlock(&Giant);
131 mtx_unlock(sc->sim_lock);
134 return(ENXIO);
135 }
136
137 tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path");
138 if (xpt_create_path(&sc->path, NULL,
139 cam_sim_path(sc->sim),
140 CAM_TARGET_WILDCARD,
141 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
142 xpt_bus_deregister(cam_sim_path (sc->sim));
143 /* Passing TRUE to cam_sim_free will free the devq as well. */
144 cam_sim_free(sc->sim, TRUE);
145 tw_osli_printf(sc, "error = %d",
146 TW_CL_SEVERITY_ERROR_STRING,
147 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
148 0x2103,
149 "Failed to create path",
150 ENXIO);
132 return(ENXIO);
133 }
134
135 tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path");
136 if (xpt_create_path(&sc->path, NULL,
137 cam_sim_path(sc->sim),
138 CAM_TARGET_WILDCARD,
139 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
140 xpt_bus_deregister(cam_sim_path (sc->sim));
141 /* Passing TRUE to cam_sim_free will free the devq as well. */
142 cam_sim_free(sc->sim, TRUE);
143 tw_osli_printf(sc, "error = %d",
144 TW_CL_SEVERITY_ERROR_STRING,
145 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
146 0x2103,
147 "Failed to create path",
148 ENXIO);
151 mtx_unlock(&Giant);
149 mtx_unlock(sc->sim_lock);
152 return(ENXIO);
153 }
154
155 tw_osli_dbg_dprintf(3, sc, "Calling xpt_setup_ccb");
150 return(ENXIO);
151 }
152
153 tw_osli_dbg_dprintf(3, sc, "Calling xpt_setup_ccb");
156 xpt_setup_ccb(&csa.ccb_h, sc->path, 5);
157 csa.ccb_h.func_code = XPT_SASYNC_CB;
158 csa.event_enable = AC_FOUND_DEVICE | AC_LOST_DEVICE;
159 csa.callback = twa_async;
160 csa.callback_arg = sc;
161 xpt_action((union ccb *)&csa);
162 mtx_unlock(&Giant);
154 mtx_unlock(sc->sim_lock);
163
164 tw_osli_dbg_dprintf(3, sc, "Calling tw_osli_request_bus_scan");
165 /*
166 * Request a bus scan, so that CAM gets to know of
167 * the logical units that we control.
168 */
169 if ((error = tw_osli_request_bus_scan(sc)))
170 tw_osli_printf(sc, "error = %d",

--- 17 unchanged lines hidden (view full) ---

188 * Output: None
189 * Return value: None
190 */
191TW_VOID
192tw_osli_cam_detach(struct twa_softc *sc)
193{
194 tw_osli_dbg_dprintf(3, sc, "entered");
195
155
156 tw_osli_dbg_dprintf(3, sc, "Calling tw_osli_request_bus_scan");
157 /*
158 * Request a bus scan, so that CAM gets to know of
159 * the logical units that we control.
160 */
161 if ((error = tw_osli_request_bus_scan(sc)))
162 tw_osli_printf(sc, "error = %d",

--- 17 unchanged lines hidden (view full) ---

180 * Output: None
181 * Return value: None
182 */
183TW_VOID
184tw_osli_cam_detach(struct twa_softc *sc)
185{
186 tw_osli_dbg_dprintf(3, sc, "entered");
187
196 mtx_lock(&Giant);
188#ifdef TW_OSLI_DEFERRED_INTR_USED
189 /* - drain the taskqueue
190 Ctrl is already went down so, no more enqueuetask will
191 happen . Don't hold any locks, that task might need.
192 */
193
194 taskqueue_drain(taskqueue_fast, &(sc->deferred_intr_callback));
195#endif
196 mtx_lock(sc->sim_lock);
197
197 if (sc->path)
198 xpt_free_path(sc->path);
199 if (sc->sim) {
200 xpt_bus_deregister(cam_sim_path(sc->sim));
201 /* Passing TRUE to cam_sim_free will free the devq as well. */
202 cam_sim_free(sc->sim, TRUE);
203 }
198 if (sc->path)
199 xpt_free_path(sc->path);
200 if (sc->sim) {
201 xpt_bus_deregister(cam_sim_path(sc->sim));
202 /* Passing TRUE to cam_sim_free will free the devq as well. */
203 cam_sim_free(sc->sim, TRUE);
204 }
204 mtx_unlock(&Giant);
205 /* It's ok have 1 hold count while destroying the mutex */
206 mtx_destroy(sc->sim_lock);
205}
206
207
208
209/*
210 * Function name: tw_osli_execute_scsi
211 * Description: Build a fw cmd, based on a CAM style ccb, and
212 * send it down.

--- 177 unchanged lines hidden (view full) ---

390
391 case XPT_RESET_BUS:
392 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
393 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
394 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
395 "Received Reset Bus request from CAM",
396 " ");
397
207}
208
209
210
211/*
212 * Function name: tw_osli_execute_scsi
213 * Description: Build a fw cmd, based on a CAM style ccb, and
214 * send it down.

--- 177 unchanged lines hidden (view full) ---

392
393 case XPT_RESET_BUS:
394 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
395 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
396 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
397 "Received Reset Bus request from CAM",
398 " ");
399
400 mtx_unlock(sc->sim_lock);
398 if (tw_cl_reset_ctlr(&sc->ctlr_handle)) {
399 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
400 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
401 0x2109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
402 "Failed to reset bus",
403 " ");
404 ccb_h->status = CAM_REQ_CMP_ERR;
405 }
406 else
407 ccb_h->status = CAM_REQ_CMP;
408
401 if (tw_cl_reset_ctlr(&sc->ctlr_handle)) {
402 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
403 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
404 0x2109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
405 "Failed to reset bus",
406 " ");
407 ccb_h->status = CAM_REQ_CMP_ERR;
408 }
409 else
410 ccb_h->status = CAM_REQ_CMP;
411
412 mtx_lock(sc->sim_lock);
409 xpt_done(ccb);
410 break;
411
412 case XPT_SET_TRAN_SETTINGS:
413 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS");
414
415 /*
416 * This command is not supported, since it's very specific

--- 99 unchanged lines hidden (view full) ---

516 tw_cl_interrupt(&(sc->ctlr_handle));
517 tw_cl_deferred_interrupt(&(sc->ctlr_handle));
518 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
519}
520
521
522
523/*
413 xpt_done(ccb);
414 break;
415
416 case XPT_SET_TRAN_SETTINGS:
417 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS");
418
419 /*
420 * This command is not supported, since it's very specific

--- 99 unchanged lines hidden (view full) ---

520 tw_cl_interrupt(&(sc->ctlr_handle));
521 tw_cl_deferred_interrupt(&(sc->ctlr_handle));
522 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
523}
524
525
526
527/*
524 * Function name: twa_async
525 * Description: Driver entry point for CAM to notify driver of special
526 * events. We don't use this for now.
527 *
528 * Input: callback_arg -- ptr to per ctlr structure
529 * code -- code associated with the event
530 * path -- cam path
531 * arg --
532 * Output: None
533 * Return value: 0 -- success
534 * non-zero-- failure
535 */
536TW_VOID
537twa_async(TW_VOID *callback_arg, TW_UINT32 code,
538 struct cam_path *path, TW_VOID *arg)
539{
540#ifdef TW_OSL_DEBUG
541 struct twa_softc *sc = (struct twa_softc *)callback_arg;
542#endif /* TW_OSL_DEBUG */
543
544 tw_osli_dbg_dprintf(3, sc, "sc = %p, code = %x, path = %p, arg = %p",
545 sc, code, path, arg);
546}
547
548
549
550/*
551 * Function name: twa_timeout
552 * Description: Driver entry point for being alerted on a request
553 * timing out.
554 *
555 * Input: arg -- ptr to timed out request
556 * Output: None
557 * Return value: None
558 */

--- 31 unchanged lines hidden (view full) ---

590 tw_osli_dbg_dprintf(3, sc, "entering");
591
592 /* If we get here before sc->sim is initialized, return an error. */
593 if (!(sc->sim))
594 return(ENXIO);
595 if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL)
596 return(ENOMEM);
597 bzero(ccb, sizeof(union ccb));
528 * Function name: twa_timeout
529 * Description: Driver entry point for being alerted on a request
530 * timing out.
531 *
532 * Input: arg -- ptr to timed out request
533 * Output: None
534 * Return value: None
535 */

--- 31 unchanged lines hidden (view full) ---

567 tw_osli_dbg_dprintf(3, sc, "entering");
568
569 /* If we get here before sc->sim is initialized, return an error. */
570 if (!(sc->sim))
571 return(ENXIO);
572 if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL)
573 return(ENOMEM);
574 bzero(ccb, sizeof(union ccb));
598 mtx_lock(&Giant);
575 mtx_lock(sc->sim_lock);
599 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sim),
600 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
601 free(ccb, M_TEMP);
576 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sim),
577 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
578 free(ccb, M_TEMP);
602 mtx_unlock(&Giant);
579 mtx_unlock(sc->sim_lock);
603 return(EIO);
604 }
605
580 return(EIO);
581 }
582
583 /* Release simq at the end of a reset */
584 if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) {
585 xpt_release_simq(sc->sim, 1);
586 sc->state &= ~TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
587 }
588
606 xpt_setup_ccb(&ccb->ccb_h, path, 5);
607 ccb->ccb_h.func_code = XPT_SCAN_BUS;
608 ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
609 ccb->crcn.flags = CAM_FLAG_NONE;
610 xpt_action(ccb);
589 xpt_setup_ccb(&ccb->ccb_h, path, 5);
590 ccb->ccb_h.func_code = XPT_SCAN_BUS;
591 ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
592 ccb->crcn.flags = CAM_FLAG_NONE;
593 xpt_action(ccb);
611 mtx_unlock(&Giant);
594 mtx_unlock(sc->sim_lock);
612 return(0);
613}
614
615
616
617/*
618 * Function name: twa_bus_scan_cb
619 * Description: Callback from CAM on a bus scan request.

--- 48 unchanged lines hidden (view full) ---

668 *
669 * Input: sc -- ptr to OSL internal ctlr context
670 * Output: None
671 * Return value: None
672 */
673TW_VOID
674tw_osli_disallow_new_requests(struct twa_softc *sc)
675{
595 return(0);
596}
597
598
599
600/*
601 * Function name: twa_bus_scan_cb
602 * Description: Callback from CAM on a bus scan request.

--- 48 unchanged lines hidden (view full) ---

651 *
652 * Input: sc -- ptr to OSL internal ctlr context
653 * Output: None
654 * Return value: None
655 */
656TW_VOID
657tw_osli_disallow_new_requests(struct twa_softc *sc)
658{
676 mtx_lock(&Giant);
677 xpt_freeze_simq(sc->sim, 1);
678 mtx_unlock(&Giant);
679 sc->state |= TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
659 /* Don't double freeze if already frozen */
660 if ((sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) == 0) {
661 mtx_lock(sc->sim_lock);
662 xpt_freeze_simq(sc->sim, 1);
663 mtx_unlock(sc->sim_lock);
664 sc->state |= TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
665 }
680}
681
682
683
684/*
685 * Function name: tw_osl_ctlr_busy
686 * Description: CL calls this function on cmd queue full or otherwise,
687 * when it is too busy to accept new requests.

--- 120 unchanged lines hidden (view full) ---

808
809 ccb->csio.scsi_status = scsi_req->scsi_status;
810 /* If simq is frozen, unfreeze it. */
811 if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN)
812 tw_osli_allow_new_requests(sc, (TW_VOID *)ccb);
813 }
814
815 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
666}
667
668
669
670/*
671 * Function name: tw_osl_ctlr_busy
672 * Description: CL calls this function on cmd queue full or otherwise,
673 * when it is too busy to accept new requests.

--- 120 unchanged lines hidden (view full) ---

794
795 ccb->csio.scsi_status = scsi_req->scsi_status;
796 /* If simq is frozen, unfreeze it. */
797 if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN)
798 tw_osli_allow_new_requests(sc, (TW_VOID *)ccb);
799 }
800
801 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
802 mtx_lock(sc->sim_lock);
816 xpt_done(ccb);
803 xpt_done(ccb);
804 mtx_unlock(sc->sim_lock);
817 if (! req->error_code)
818 /* twa_action will free the request otherwise */
819 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
820}
821
805 if (! req->error_code)
806 /* twa_action will free the request otherwise */
807 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
808}
809