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 209268 2010-06-17 19:48:03Z 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 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
88 /*
89 * It's an internal request. Set the appropriate
90 * error and call the CL internal callback if there's
91 * one. If the request originator is polling for
92 * completion, he should be checking req->error to
93 * determine that the request did not go through.
94 * The request originators are responsible for the
95 * clean-up.
96 */
97 req->error_code = TW_CL_ERR_REQ_BUS_RESET;
98 if (req->tw_cli_callback)
99 req->tw_cli_callback(req);
100 } else {
101 if ((req_pkt = req->orig_req)) {
102 /* It's a SCSI request. Complete it. */
103 tw_cli_dbg_printf(2, ctlr->ctlr_handle,
104 tw_osl_cur_func(),
105 "Completing complete request %p "
106 "on reset",
107 req);
108 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
109 req_pkt->tw_osl_callback(req->req_handle);
110 }
111 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
112 }
113 }
114}
115
116
117
118/*
119 * Function name: tw_cli_drain_busy_queue
120 * Description: This function gets called during a controller reset.
121 * It errors back to the OS Layer, all those requests that

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

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

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

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

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

234 TW_UINT32 resp;
235 TW_UINT32 status_reg;
236
237 tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
238
239 for (;;) {
240 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
241
242 if (tw_cli_check_ctlr_state(ctlr, status_reg))
243 return(TW_OSL_EGENFAILURE);
244
245 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
246 return(TW_OSL_ESUCCESS); /* no more response queue entries */
247
248 resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle);
249 }
250}
251
252

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

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

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

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

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

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

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

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

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

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

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

845 if (reg & TWA_STATUS_COMMAND_INTERRUPT)
846 tw_osl_strcpy(&str[tw_osl_strlen(str)], "CMD_INTR,");
847 if (reg & TWA_STATUS_ATTENTION_INTERRUPT)
848 tw_osl_strcpy(&str[tw_osl_strlen(str)], "ATTN_INTR,");
849 if (reg & TWA_STATUS_HOST_INTERRUPT)
850 tw_osl_strcpy(&str[tw_osl_strlen(str)], "HOST_INTR,");
851 if (reg & TWA_STATUS_PCI_ABORT_INTERRUPT)
852 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_ABRT,");
853 if (reg & TWA_STATUS_MICROCONTROLLER_ERROR)
854 tw_osl_strcpy(&str[tw_osl_strlen(str)], "MC_ERR,");
855 if (reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT)
856 tw_osl_strcpy(&str[tw_osl_strlen(str)], "Q_ERR,");
857 if (reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT)
858 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_PERR");
859
860 tw_osl_strcpy(&str[tw_osl_strlen(str)], "]");
861 return(str);
862}

--- 177 unchanged lines hidden ---