Deleted Added
sdiff udiff text old ( 209268 ) new ( 212008 )
full compact
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_cl_misc.c 212008 2010-08-30 19:15:04Z delphij $
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

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

78tw_cli_drain_complete_queue(struct tw_cli_ctlr_context *ctlr)
79{
80 struct tw_cli_req_context *req;
81 struct tw_cl_req_packet *req_pkt;
82
83 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
84
85 /* Walk the busy queue. */
86 while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q)) !=
87 TW_CL_NULL) {
88 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
89 /*
90 * It's an internal request. Set the appropriate
91 * error and call the CL internal callback if there's
92 * one. If the request originator is polling for
93 * completion, he should be checking req->error to
94 * determine that the request did not go through.
95 * The request originators are responsible for the
96 * clean-up.
97 */
98 req->error_code = TW_CL_ERR_REQ_BUS_RESET;
99 if (req->tw_cli_callback)
100 req->tw_cli_callback(req);
101 } else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
102 /* It's a passthru request. Complete it. */
103 if ((req_pkt = req->orig_req) != TW_CL_NULL) {
104 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
105
106 if (req_pkt->tw_osl_callback)
107 req_pkt->tw_osl_callback(req->req_handle);
108 }
109 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
110 } else {
111 /* It's an external (SCSI) request. Add it to the reset queue. */
112 tw_osl_untimeout(req->req_handle);
113 tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
114 }
115 } /* End of while loop */
116}
117
118
119
120/*
121 * Function name: tw_cli_drain_busy_queue
122 * Description: This function gets called during a controller reset.
123 * It errors back to the OS Layer, all those requests that

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

132tw_cli_drain_busy_queue(struct tw_cli_ctlr_context *ctlr)
133{
134 struct tw_cli_req_context *req;
135 struct tw_cl_req_packet *req_pkt;
136
137 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
138
139 /* Walk the busy queue. */
140 while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_BUSY_Q)) !=
141 TW_CL_NULL) {
142 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
143 /*
144 * It's an internal request. Set the appropriate
145 * error and call the CL internal callback if there's
146 * one. If the request originator is polling for
147 * completion, he should be checking req->error to
148 * determine that the request did not go through.
149 * The request originators are responsible for the
150 * clean-up.
151 */
152 req->error_code = TW_CL_ERR_REQ_BUS_RESET;
153 if (req->tw_cli_callback)
154 req->tw_cli_callback(req);
155 } else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
156 /* It's a passthru request. Complete it. */
157 if ((req_pkt = req->orig_req) != TW_CL_NULL) {
158 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
159
160 if (req_pkt->tw_osl_callback)
161 req_pkt->tw_osl_callback(req->req_handle);
162 }
163 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
164 } else {
165 /* It's an external (SCSI) request. Add it to the reset queue. */
166 tw_osl_untimeout(req->req_handle);
167 tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
168 }
169 } /* End of while loop */
170}
171
172
173
174/*
175 * Function name: tw_cli_drain_pending_queue
176 * Description: This function gets called during a controller reset.
177 * It errors back to the OS Layer, all those requests that

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

188 struct tw_cli_req_context *req;
189 struct tw_cl_req_packet *req_pkt;
190
191 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
192
193 /*
194 * Pull requests off the pending queue, and complete them.
195 */
196 while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q)) !=
197 TW_CL_NULL) {
198 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
199 /*
200 * It's an internal request. Set the appropriate
201 * error and call the CL internal callback if there's
202 * one. If the request originator is polling for
203 * completion, he should be checking req->error to
204 * determine that the request did not go through.
205 * The request originators are responsible for the
206 * clean-up.
207 */
208 req->error_code = TW_CL_ERR_REQ_BUS_RESET;
209 if (req->tw_cli_callback)
210 req->tw_cli_callback(req);
211 } else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
212 /* It's a passthru request. Complete it. */
213 if ((req_pkt = req->orig_req) != TW_CL_NULL) {
214 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
215
216 if (req_pkt->tw_osl_callback)
217 req_pkt->tw_osl_callback(req->req_handle);
218 }
219 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
220 } else {
221 /* It's an external (SCSI) request. Add it to the reset queue. */
222 tw_osl_untimeout(req->req_handle);
223 tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
224 }
225 } /* End of while loop */
226}
227
228
229
230/*
231 * Function name: tw_cli_drain_response_queue
232 * Description: Drain the controller response queue.
233 *

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

242 TW_UINT32 resp;
243 TW_UINT32 status_reg;
244
245 tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
246
247 for (;;) {
248 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
249
250 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
251 return(TW_OSL_ESUCCESS); /* no more response queue entries */
252
253 resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle);
254 }
255}
256
257

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

273 TW_INT32 resp_id;
274 TW_UINT32 status_reg;
275
276 tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
277
278 for (;;) {
279 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
280
281 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
282 return(TW_OSL_ENOTTY); /* no more response queue entries */
283
284 if (ctlr->device_id == TW_CL_DEVICE_ID_9K) {
285 resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle);
286 resp_id = GET_RESP_ID(resp);
287 } else {
288 resp = TW_CLI_READ_LARGE_RESPONSE_QUEUE(

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

353
354 if (req->state != TW_CLI_REQ_STATE_COMPLETE) {
355 error = TW_OSL_ETIMEDOUT;
356 break;
357 }
358
359 if ((error = req->cmd_pkt->command.cmd_pkt_9k.status)) {
360 cmd_hdr = &req->cmd_pkt->cmd_hdr;
361#if 0
362 tw_cli_create_ctlr_event(ctlr,
363 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
364 cmd_hdr);
365#endif // 0
366 break;
367 }
368
369 aen_code = tw_cli_manage_aen(ctlr, req);
370 if (aen_code == TWA_AEN_QUEUE_EMPTY)
371 break;
372 if (aen_code == TWA_AEN_SYNC_TIME_WITH_HOST)
373 continue;

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

713 tw_cli_dbg_printf(8, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
714
715 /* Check if the 'micro-controller ready' bit is not set. */
716 if (!(status_reg & TWA_STATUS_MICROCONTROLLER_READY)) {
717 TW_INT8 desc[200];
718
719 tw_osl_memzero(desc, 200);
720 if (!(ctlr->reset_phase1_in_progress)) {
721 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
722 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
723 0x1301, 0x1, TW_CL_SEVERITY_ERROR_STRING,
724 "Missing expected status bit(s)",
725 "status reg = 0x%x; Missing bits: %s",
726 status_reg,
727 tw_cli_describe_bits(
728 TWA_STATUS_MICROCONTROLLER_READY,
729 desc));

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

737
738 tw_osl_memzero(desc, 200);
739
740 /* Skip queue error msgs during 9650SE/9690SA reset */
741 if (((ctlr->device_id != TW_CL_DEVICE_ID_9K_E) &&
742 (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
743 (!(ctlr->reset_in_progress)) ||
744 ((status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) == 0))
745 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
746 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
747 0x1302, 0x1, TW_CL_SEVERITY_ERROR_STRING,
748 "Unexpected status bit(s)",
749 "status reg = 0x%x Unexpected bits: %s",
750 status_reg & TWA_STATUS_UNEXPECTED_BITS,
751 tw_cli_describe_bits(status_reg &
752 TWA_STATUS_UNEXPECTED_BITS, desc));
753
754 if (status_reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT) {
755 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
756 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
757 0x1303, 0x1, TW_CL_SEVERITY_ERROR_STRING,
758 "PCI parity error: clearing... "
759 "Re-seat/move/replace card",
760 "status reg = 0x%x %s",
761 status_reg,
762 tw_cli_describe_bits(status_reg, desc));
763 TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
764 TWA_CONTROL_CLEAR_PARITY_ERROR);
765
766#ifdef TW_OSL_PCI_CONFIG_ACCESSIBLE
767 tw_osl_write_pci_config(ctlr->ctlr_handle,
768 TW_CLI_PCI_CONFIG_STATUS_OFFSET,
769 TWA_PCI_CONFIG_CLEAR_PARITY_ERROR, 2);
770#endif /* TW_OSL_PCI_CONFIG_ACCESSIBLE */
771
772 }
773
774 if (status_reg & TWA_STATUS_PCI_ABORT_INTERRUPT) {
775 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
776 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
777 0x1304, 0x1, TW_CL_SEVERITY_ERROR_STRING,
778 "PCI abort: clearing... ",
779 "status reg = 0x%x %s",
780 status_reg,
781 tw_cli_describe_bits(status_reg, desc));
782 TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
783 TWA_CONTROL_CLEAR_PCI_ABORT);

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

790
791 }
792
793 if (status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) {
794 /* Skip queue error msgs during 9650SE/9690SA reset */
795 if (((ctlr->device_id != TW_CL_DEVICE_ID_9K_E) &&
796 (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
797 (!(ctlr->reset_in_progress)))
798 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
799 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
800 0x1305, 0x1, TW_CL_SEVERITY_ERROR_STRING,
801 "Controller queue error: clearing... ",
802 "status reg = 0x%x %s",
803 status_reg,
804 tw_cli_describe_bits(status_reg, desc));
805 TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
806 TWA_CONTROL_CLEAR_QUEUE_ERROR);
807 }
808 }
809 return(error);
810}
811
812
813
814/*
815 * Function name: tw_cli_describe_bits

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

838 if (reg & TWA_STATUS_COMMAND_INTERRUPT)
839 tw_osl_strcpy(&str[tw_osl_strlen(str)], "CMD_INTR,");
840 if (reg & TWA_STATUS_ATTENTION_INTERRUPT)
841 tw_osl_strcpy(&str[tw_osl_strlen(str)], "ATTN_INTR,");
842 if (reg & TWA_STATUS_HOST_INTERRUPT)
843 tw_osl_strcpy(&str[tw_osl_strlen(str)], "HOST_INTR,");
844 if (reg & TWA_STATUS_PCI_ABORT_INTERRUPT)
845 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_ABRT,");
846 if (reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT)
847 tw_osl_strcpy(&str[tw_osl_strlen(str)], "Q_ERR,");
848 if (reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT)
849 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_PERR");
850
851 tw_osl_strcpy(&str[tw_osl_strlen(str)], "]");
852 return(str);
853}

--- 177 unchanged lines hidden ---