Deleted Added
full compact
tw_cl_io.c (208969) tw_cl_io.c (212008)
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_cl_io.c 208969 2010-06-09 21:40:38Z delphij $
27 * $FreeBSD: head/sys/dev/twa/tw_cl_io.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

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

69TW_INT32
70tw_cl_start_io(struct tw_cl_ctlr_handle *ctlr_handle,
71 struct tw_cl_req_packet *req_pkt, struct tw_cl_req_handle *req_handle)
72{
73 struct tw_cli_ctlr_context *ctlr;
74 struct tw_cli_req_context *req;
75 struct tw_cl_command_9k *cmd;
76 struct tw_cl_scsi_req_packet *scsi_req;
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

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

69TW_INT32
70tw_cl_start_io(struct tw_cl_ctlr_handle *ctlr_handle,
71 struct tw_cl_req_packet *req_pkt, struct tw_cl_req_handle *req_handle)
72{
73 struct tw_cli_ctlr_context *ctlr;
74 struct tw_cli_req_context *req;
75 struct tw_cl_command_9k *cmd;
76 struct tw_cl_scsi_req_packet *scsi_req;
77 TW_INT32 error;
77 TW_INT32 error = TW_CL_ERR_REQ_SUCCESS;
78
79 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
80
81 ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
82
78
79 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
80
81 ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
82
83 if (ctlr->reset_in_progress) {
84 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
85 "I/O during reset: returning busy.");
86 return(TW_OSL_EBUSY);
87 }
88
89 /*
90 * If working with a firmware version that does not support multiple
91 * luns, and this request is directed at a non-zero lun, error it
92 * back right away.
93 */
94 if ((req_pkt->gen_req_pkt.scsi_req.lun) &&
95 (ctlr->working_srl < TWA_MULTI_LUN_FW_SRL)) {
96 req_pkt->status |= (TW_CL_ERR_REQ_INVALID_LUN |

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

140 } else {
141 cmd->lun_h4__sgl_entries =
142 TW_CL_SWAP16(BUILD_LUN_H4__SGL_ENTRIES(scsi_req->lun,
143 scsi_req->sgl_entries));
144 tw_cli_fill_sg_list(ctlr, scsi_req->sg_list,
145 cmd->sg_list, scsi_req->sgl_entries);
146 }
147
83 /*
84 * If working with a firmware version that does not support multiple
85 * luns, and this request is directed at a non-zero lun, error it
86 * back right away.
87 */
88 if ((req_pkt->gen_req_pkt.scsi_req.lun) &&
89 (ctlr->working_srl < TWA_MULTI_LUN_FW_SRL)) {
90 req_pkt->status |= (TW_CL_ERR_REQ_INVALID_LUN |

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

134 } else {
135 cmd->lun_h4__sgl_entries =
136 TW_CL_SWAP16(BUILD_LUN_H4__SGL_ENTRIES(scsi_req->lun,
137 scsi_req->sgl_entries));
138 tw_cli_fill_sg_list(ctlr, scsi_req->sg_list,
139 cmd->sg_list, scsi_req->sgl_entries);
140 }
141
148 if ((error = tw_cli_submit_cmd(req))) {
142 if (((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL) ||
143 (ctlr->reset_in_progress)) {
144 tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
145 TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
146 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
147 } else if ((error = tw_cli_submit_cmd(req))) {
149 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
150 "Could not start request. request = %p, error = %d",
151 req, error);
152 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
153 }
154 return(error);
155}
156

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

166 * non-zero-- failure
167 */
168TW_INT32
169tw_cli_submit_cmd(struct tw_cli_req_context *req)
170{
171 struct tw_cli_ctlr_context *ctlr = req->ctlr;
172 struct tw_cl_ctlr_handle *ctlr_handle = ctlr->ctlr_handle;
173 TW_UINT32 status_reg;
148 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
149 "Could not start request. request = %p, error = %d",
150 req, error);
151 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
152 }
153 return(error);
154}
155

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

165 * non-zero-- failure
166 */
167TW_INT32
168tw_cli_submit_cmd(struct tw_cli_req_context *req)
169{
170 struct tw_cli_ctlr_context *ctlr = req->ctlr;
171 struct tw_cl_ctlr_handle *ctlr_handle = ctlr->ctlr_handle;
172 TW_UINT32 status_reg;
174 TW_INT32 error;
173 TW_INT32 error = 0;
175
176 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
177
178 /* Serialize access to the controller cmd queue. */
179 tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
180
181 /* For 9650SE first write low 4 bytes */
182 if ((ctlr->device_id == TW_CL_DEVICE_ID_9K_E) ||
183 (ctlr->device_id == TW_CL_DEVICE_ID_9K_SA))
184 tw_osl_write_reg(ctlr_handle,
185 TWA_COMMAND_QUEUE_OFFSET_LOW,
186 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
187
174
175 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
176
177 /* Serialize access to the controller cmd queue. */
178 tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
179
180 /* For 9650SE first write low 4 bytes */
181 if ((ctlr->device_id == TW_CL_DEVICE_ID_9K_E) ||
182 (ctlr->device_id == TW_CL_DEVICE_ID_9K_SA))
183 tw_osl_write_reg(ctlr_handle,
184 TWA_COMMAND_QUEUE_OFFSET_LOW,
185 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
186
188 /* Check to see if we can post a command. */
189 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
187 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
190 if ((error = tw_cli_check_ctlr_state(ctlr, status_reg)))
191 goto out;
192
193 if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
194 struct tw_cl_req_packet *req_pkt =
195 (struct tw_cl_req_packet *)(req->orig_req);
196
197 tw_cli_dbg_printf(7, ctlr_handle, tw_osl_cur_func(),
198 "Cmd queue full");
199
200 if ((req->flags & TW_CLI_REQ_FLAGS_INTERNAL)
201 || ((req_pkt) &&
202 (req_pkt->flags & TW_CL_REQ_RETRY_ON_BUSY))
203 ) {
204 if (req->state != TW_CLI_REQ_STATE_PENDING) {
205 tw_cli_dbg_printf(2, ctlr_handle,
206 tw_osl_cur_func(),
207 "pending internal/ioctl request");
208 req->state = TW_CLI_REQ_STATE_PENDING;
209 tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
188 if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
189 struct tw_cl_req_packet *req_pkt =
190 (struct tw_cl_req_packet *)(req->orig_req);
191
192 tw_cli_dbg_printf(7, ctlr_handle, tw_osl_cur_func(),
193 "Cmd queue full");
194
195 if ((req->flags & TW_CLI_REQ_FLAGS_INTERNAL)
196 || ((req_pkt) &&
197 (req_pkt->flags & TW_CL_REQ_RETRY_ON_BUSY))
198 ) {
199 if (req->state != TW_CLI_REQ_STATE_PENDING) {
200 tw_cli_dbg_printf(2, ctlr_handle,
201 tw_osl_cur_func(),
202 "pending internal/ioctl request");
203 req->state = TW_CLI_REQ_STATE_PENDING;
204 tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
210 error = 0;
211 /* Unmask command interrupt. */
212 TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
213 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
214 } else
215 error = TW_OSL_EBUSY;
216 } else {
205 /* Unmask command interrupt. */
206 TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
207 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
208 } else
209 error = TW_OSL_EBUSY;
210 } else {
217 tw_osl_ctlr_busy(ctlr_handle, req->req_handle);
218 error = TW_OSL_EBUSY;
219 }
220 } else {
221 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(),
222 "Submitting command");
223
224 /* Insert command into busy queue */
225 req->state = TW_CLI_REQ_STATE_BUSY;

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

241 TWA_COMMAND_QUEUE_OFFSET_HIGH,
242 (TW_UINT32)(((TW_UINT64)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)))>>32), 4);
243 } else
244 tw_osl_write_reg(ctlr_handle,
245 TWA_COMMAND_QUEUE_OFFSET,
246 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
247 }
248 }
211 error = TW_OSL_EBUSY;
212 }
213 } else {
214 tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(),
215 "Submitting command");
216
217 /* Insert command into busy queue */
218 req->state = TW_CLI_REQ_STATE_BUSY;

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

234 TWA_COMMAND_QUEUE_OFFSET_HIGH,
235 (TW_UINT32)(((TW_UINT64)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)))>>32), 4);
236 } else
237 tw_osl_write_reg(ctlr_handle,
238 TWA_COMMAND_QUEUE_OFFSET,
239 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
240 }
241 }
249out:
242
250 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
251
252 return(error);
253}
254
255
256
257/*

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

272 struct tw_cli_ctlr_context *ctlr;
273 struct tw_cli_req_context *req;
274 union tw_cl_command_7k *cmd_7k;
275 struct tw_cl_command_9k *cmd_9k;
276 struct tw_cl_passthru_req_packet *pt_req;
277 TW_UINT8 opcode;
278 TW_UINT8 sgl_offset;
279 TW_VOID *sgl = TW_CL_NULL;
243 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
244
245 return(error);
246}
247
248
249
250/*

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

265 struct tw_cli_ctlr_context *ctlr;
266 struct tw_cli_req_context *req;
267 union tw_cl_command_7k *cmd_7k;
268 struct tw_cl_command_9k *cmd_9k;
269 struct tw_cl_passthru_req_packet *pt_req;
270 TW_UINT8 opcode;
271 TW_UINT8 sgl_offset;
272 TW_VOID *sgl = TW_CL_NULL;
280 TW_INT32 error;
273 TW_INT32 error = TW_CL_ERR_REQ_SUCCESS;
281
282 tw_cli_dbg_printf(5, ctlr_handle, tw_osl_cur_func(), "entered");
283
284 ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
285
274
275 tw_cli_dbg_printf(5, ctlr_handle, tw_osl_cur_func(), "entered");
276
277 ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
278
286 if (ctlr->reset_in_progress) {
287 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
288 "Passthru request during reset: returning busy.");
289 return(TW_OSL_EBUSY);
290 }
291
292 if ((req = tw_cli_get_request(ctlr
293 )) == TW_CL_NULL) {
294 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
295 "Out of request context packets: returning busy");
296 return(TW_OSL_EBUSY);
297 }
298
299 req_handle->cl_req_ctxt = req;
300 req->req_handle = req_handle;
301 req->orig_req = req_pkt;
302 req->tw_cli_callback = tw_cli_complete_io;
303
279 if ((req = tw_cli_get_request(ctlr
280 )) == TW_CL_NULL) {
281 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
282 "Out of request context packets: returning busy");
283 return(TW_OSL_EBUSY);
284 }
285
286 req_handle->cl_req_ctxt = req;
287 req->req_handle = req_handle;
288 req->orig_req = req_pkt;
289 req->tw_cli_callback = tw_cli_complete_io;
290
304 req->flags |= (TW_CLI_REQ_FLAGS_EXTERNAL | TW_CLI_REQ_FLAGS_PASSTHRU);
291 req->flags |= TW_CLI_REQ_FLAGS_PASSTHRU;
305
306 pt_req = &(req_pkt->gen_req_pkt.pt_req);
307
308 tw_osl_memcpy(req->cmd_pkt, pt_req->cmd_pkt,
309 pt_req->cmd_pkt_length);
310 /* Build the cmd pkt. */
311 if ((opcode = GET_OPCODE(((TW_UINT8 *)
312 (pt_req->cmd_pkt))[sizeof(struct tw_cl_command_header)]))

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

343 ((ctlr->flags & TW_CL_64BIT_ADDRESSES) ? 3 : 2);
344 }
345 }
346
347 if (sgl)
348 tw_cli_fill_sg_list(ctlr, pt_req->sg_list,
349 sgl, pt_req->sgl_entries);
350
292
293 pt_req = &(req_pkt->gen_req_pkt.pt_req);
294
295 tw_osl_memcpy(req->cmd_pkt, pt_req->cmd_pkt,
296 pt_req->cmd_pkt_length);
297 /* Build the cmd pkt. */
298 if ((opcode = GET_OPCODE(((TW_UINT8 *)
299 (pt_req->cmd_pkt))[sizeof(struct tw_cl_command_header)]))

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

330 ((ctlr->flags & TW_CL_64BIT_ADDRESSES) ? 3 : 2);
331 }
332 }
333
334 if (sgl)
335 tw_cli_fill_sg_list(ctlr, pt_req->sg_list,
336 sgl, pt_req->sgl_entries);
337
351 if ((error = tw_cli_submit_cmd(req))) {
338 if (((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL) ||
339 (ctlr->reset_in_progress)) {
340 tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
341 TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
342 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
343 } else if ((error = tw_cli_submit_cmd(req))) {
352 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
353 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
354 0x1100, 0x1, TW_CL_SEVERITY_ERROR_STRING,
355 "Failed to start passthru command",
356 "error = %d", error);
357 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
358 }
359 return(error);

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

755
756 /* Build the cmd pkt. */
757 cmd = &(req->cmd_pkt->command.cmd_pkt_7k);
758
759 req->cmd_pkt->cmd_hdr.header_desc.size_header = 128;
760
761 cmd->param.sgl_off__opcode =
762 BUILD_SGL_OFF__OPCODE(2, TWA_FW_CMD_GET_PARAM);
344 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
345 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
346 0x1100, 0x1, TW_CL_SEVERITY_ERROR_STRING,
347 "Failed to start passthru command",
348 "error = %d", error);
349 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
350 }
351 return(error);

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

747
748 /* Build the cmd pkt. */
749 cmd = &(req->cmd_pkt->command.cmd_pkt_7k);
750
751 req->cmd_pkt->cmd_hdr.header_desc.size_header = 128;
752
753 cmd->param.sgl_off__opcode =
754 BUILD_SGL_OFF__OPCODE(2, TWA_FW_CMD_GET_PARAM);
763 cmd->param.request_id =
764 (TW_UINT8)(TW_CL_SWAP16(req->request_id));
755 cmd->param.request_id = (TW_UINT8)(TW_CL_SWAP16(req->request_id));
765 cmd->param.host_id__unit = BUILD_HOST_ID__UNIT(0, 0);
766 cmd->param.param_count = TW_CL_SWAP16(1);
767
768 if (ctlr->flags & TW_CL_64BIT_ADDRESSES) {
769 ((struct tw_cl_sg_desc64 *)(cmd->param.sgl))[0].address =
770 TW_CL_SWAP64(req->data_phys);
771 ((struct tw_cl_sg_desc64 *)(cmd->param.sgl))[0].length =
772 TW_CL_SWAP32(req->length);

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

784 param->parameter_id = (TW_UINT8)(param_id);
785 param->parameter_size_bytes = TW_CL_SWAP16(param_size);
786
787 /* Submit the command. */
788 if (callback == TW_CL_NULL) {
789 /* There's no call back; wait till the command completes. */
790 error = tw_cli_submit_and_poll_request(req,
791 TW_CLI_REQUEST_TIMEOUT_PERIOD);
756 cmd->param.host_id__unit = BUILD_HOST_ID__UNIT(0, 0);
757 cmd->param.param_count = TW_CL_SWAP16(1);
758
759 if (ctlr->flags & TW_CL_64BIT_ADDRESSES) {
760 ((struct tw_cl_sg_desc64 *)(cmd->param.sgl))[0].address =
761 TW_CL_SWAP64(req->data_phys);
762 ((struct tw_cl_sg_desc64 *)(cmd->param.sgl))[0].length =
763 TW_CL_SWAP32(req->length);

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

775 param->parameter_id = (TW_UINT8)(param_id);
776 param->parameter_size_bytes = TW_CL_SWAP16(param_size);
777
778 /* Submit the command. */
779 if (callback == TW_CL_NULL) {
780 /* There's no call back; wait till the command completes. */
781 error = tw_cli_submit_and_poll_request(req,
782 TW_CLI_REQUEST_TIMEOUT_PERIOD);
792 if (error == TW_OSL_ETIMEDOUT)
793 /* Clean-up done by tw_cli_submit_and_poll_request. */
794 return(error);
795 if (error)
796 goto out;
797 if ((error = cmd->param.status)) {
783 if (error)
784 goto out;
785 if ((error = cmd->param.status)) {
786#if 0
798 tw_cli_create_ctlr_event(ctlr,
799 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
800 &(req->cmd_pkt->cmd_hdr));
787 tw_cli_create_ctlr_event(ctlr,
788 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
789 &(req->cmd_pkt->cmd_hdr));
790#endif // 0
801 goto out;
802 }
803 tw_osl_memcpy(param_data, param->data, param_size);
804 ctlr->internal_req_busy = TW_CL_FALSE;
805 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
806 } else {
807 /* There's a call back. Simply submit the command. */
808 req->tw_cli_callback = callback;

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

900 /* Specify which parameter we want to set. */
901 param->table_id = TW_CL_SWAP16(table_id | TWA_9K_PARAM_DESCRIPTOR);
902 param->parameter_id = (TW_UINT8)(param_id);
903 param->parameter_size_bytes = TW_CL_SWAP16(param_size);
904 tw_osl_memcpy(param->data, data, param_size);
905
906 /* Submit the command. */
907 if (callback == TW_CL_NULL) {
791 goto out;
792 }
793 tw_osl_memcpy(param_data, param->data, param_size);
794 ctlr->internal_req_busy = TW_CL_FALSE;
795 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
796 } else {
797 /* There's a call back. Simply submit the command. */
798 req->tw_cli_callback = callback;

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

890 /* Specify which parameter we want to set. */
891 param->table_id = TW_CL_SWAP16(table_id | TWA_9K_PARAM_DESCRIPTOR);
892 param->parameter_id = (TW_UINT8)(param_id);
893 param->parameter_size_bytes = TW_CL_SWAP16(param_size);
894 tw_osl_memcpy(param->data, data, param_size);
895
896 /* Submit the command. */
897 if (callback == TW_CL_NULL) {
908 /* There's no call back; wait till the command completes. */
898 /* There's no call back; wait till the command completes. */
909 error = tw_cli_submit_and_poll_request(req,
899 error = tw_cli_submit_and_poll_request(req,
910 TW_CLI_REQUEST_TIMEOUT_PERIOD);
911 if (error == TW_OSL_ETIMEDOUT)
912 /* Clean-up done by tw_cli_submit_and_poll_request. */
913 return(error);
900 TW_CLI_REQUEST_TIMEOUT_PERIOD);
914 if (error)
915 goto out;
916 if ((error = cmd->param.status)) {
901 if (error)
902 goto out;
903 if ((error = cmd->param.status)) {
904#if 0
917 tw_cli_create_ctlr_event(ctlr,
918 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
919 &(req->cmd_pkt->cmd_hdr));
905 tw_cli_create_ctlr_event(ctlr,
906 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
907 &(req->cmd_pkt->cmd_hdr));
908#endif // 0
920 goto out;
921 }
922 ctlr->internal_req_busy = TW_CL_FALSE;
923 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
924 } else {
925 /* There's a call back. Simply submit the command. */
926 req->tw_cli_callback = callback;
927 if ((error = tw_cli_submit_cmd(req)))

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

1017 */
1018
1019 /*
1020 * We have to make sure that this timed out request, if it were in the
1021 * pending queue, doesn't get submitted while we are here, from
1022 * tw_cli_submit_pending_queue. There could be a race in that case.
1023 * Need to revisit.
1024 */
909 goto out;
910 }
911 ctlr->internal_req_busy = TW_CL_FALSE;
912 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
913 } else {
914 /* There's a call back. Simply submit the command. */
915 req->tw_cli_callback = callback;
916 if ((error = tw_cli_submit_cmd(req)))

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

1006 */
1007
1008 /*
1009 * We have to make sure that this timed out request, if it were in the
1010 * pending queue, doesn't get submitted while we are here, from
1011 * tw_cli_submit_pending_queue. There could be a race in that case.
1012 * Need to revisit.
1013 */
1025 if (req->state != TW_CLI_REQ_STATE_PENDING)
1026 tw_cl_reset_ctlr(ctlr->ctlr_handle);
1027 else {
1014 if (req->state == TW_CLI_REQ_STATE_PENDING) {
1028 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(),
1029 "Removing request from pending queue");
1030 /*
1031 * Request was never submitted. Clean up. Note that we did
1032 * not do a reset. So, we have to remove the request ourselves
1033 * from the pending queue (as against tw_cli_drain_pendinq_queue
1034 * taking care of it).
1035 */

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

1048
1049
1050/*
1051 * Function name: tw_cl_reset_ctlr
1052 * Description: Soft resets and then initializes the controller;
1053 * drains any incomplete requests.
1054 *
1055 * Input: ctlr -- ptr to per ctlr structure
1015 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(),
1016 "Removing request from pending queue");
1017 /*
1018 * Request was never submitted. Clean up. Note that we did
1019 * not do a reset. So, we have to remove the request ourselves
1020 * from the pending queue (as against tw_cli_drain_pendinq_queue
1021 * taking care of it).
1022 */

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

1035
1036
1037/*
1038 * Function name: tw_cl_reset_ctlr
1039 * Description: Soft resets and then initializes the controller;
1040 * drains any incomplete requests.
1041 *
1042 * Input: ctlr -- ptr to per ctlr structure
1043 * req_handle -- ptr to request handle
1056 * Output: None
1057 * Return value: 0 -- success
1058 * non-zero-- failure
1059 */
1060TW_INT32
1061tw_cl_reset_ctlr(struct tw_cl_ctlr_handle *ctlr_handle)
1062{
1063 struct tw_cli_ctlr_context *ctlr =
1064 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
1065 struct twa_softc *sc = ctlr_handle->osl_ctlr_ctxt;
1044 * Output: None
1045 * Return value: 0 -- success
1046 * non-zero-- failure
1047 */
1048TW_INT32
1049tw_cl_reset_ctlr(struct tw_cl_ctlr_handle *ctlr_handle)
1050{
1051 struct tw_cli_ctlr_context *ctlr =
1052 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
1053 struct twa_softc *sc = ctlr_handle->osl_ctlr_ctxt;
1054 struct tw_cli_req_context *req;
1066 TW_INT32 reset_attempt = 1;
1055 TW_INT32 reset_attempt = 1;
1067 TW_INT32 error;
1056 TW_INT32 error = 0;
1068
1069 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(), "entered");
1070
1071 ctlr->reset_in_progress = TW_CL_TRUE;
1057
1058 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(), "entered");
1059
1060 ctlr->reset_in_progress = TW_CL_TRUE;
1072 xpt_freeze_simq(sc->sim, 1);
1061 twa_teardown_intr(sc);
1073
1062
1074 tw_cli_disable_interrupts(ctlr);
1075
1076 /*
1077 * Error back all requests in the complete, busy, and pending queues.
1078 * If any request is already on its way to getting submitted, it's in
1079 * none of these queues and so, will not be completed. That request
1080 * will continue its course and get submitted to the controller after
1081 * the reset is done (and io_lock is released).
1082 */
1063
1064 /*
1065 * Error back all requests in the complete, busy, and pending queues.
1066 * If any request is already on its way to getting submitted, it's in
1067 * none of these queues and so, will not be completed. That request
1068 * will continue its course and get submitted to the controller after
1069 * the reset is done (and io_lock is released).
1070 */
1083 tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
1084 "Draining all queues following reset");
1085 tw_cli_drain_complete_queue(ctlr);
1086 tw_cli_drain_busy_queue(ctlr);
1087 tw_cli_drain_pending_queue(ctlr);
1088 ctlr->internal_req_busy = TW_CL_FALSE;
1089 ctlr->get_more_aens = TW_CL_FALSE;
1090
1091 /* Soft reset the controller. */
1071 tw_cli_drain_complete_queue(ctlr);
1072 tw_cli_drain_busy_queue(ctlr);
1073 tw_cli_drain_pending_queue(ctlr);
1074 ctlr->internal_req_busy = TW_CL_FALSE;
1075 ctlr->get_more_aens = TW_CL_FALSE;
1076
1077 /* Soft reset the controller. */
1092try_reset:
1093 if ((error = tw_cli_soft_reset(ctlr))) {
1094 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1095 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1096 0x1105, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1097 "Controller reset failed",
1098 "error = %d; attempt %d", error, reset_attempt++);
1099 if (reset_attempt <= TW_CLI_MAX_RESET_ATTEMPTS)
1100 goto try_reset;
1101 else
1102 goto out;
1103 }
1078 while (reset_attempt <= TW_CLI_MAX_RESET_ATTEMPTS) {
1079 if ((error = tw_cli_soft_reset(ctlr))) {
1080 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1081 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1082 0x1105, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1083 "Controller reset failed",
1084 "error = %d; attempt %d", error, reset_attempt++);
1085 reset_attempt++;
1086 continue;
1087 }
1104
1088
1105 /* Re-establish logical connection with the controller. */
1106 if ((error = tw_cli_init_connection(ctlr,
1107 (TW_UINT16)(ctlr->max_simult_reqs),
1108 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
1109 TW_CL_NULL, TW_CL_NULL))) {
1110 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1089 /* Re-establish logical connection with the controller. */
1090 if ((error = tw_cli_init_connection(ctlr,
1091 (TW_UINT16)(ctlr->max_simult_reqs),
1092 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
1093 TW_CL_NULL, TW_CL_NULL))) {
1094 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1095 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1096 0x1106, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1097 "Can't initialize connection after reset",
1098 "error = %d", error);
1099 reset_attempt++;
1100 continue;
1101 }
1102
1103#ifdef TW_OSL_DEBUG
1104 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1111 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1105 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1112 0x1106, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1113 "Can't initialize connection after reset",
1114 "error = %d", error);
1115 goto out;
1106 0x1107, 0x3, TW_CL_SEVERITY_INFO_STRING,
1107 "Controller reset done!", " ");
1108#endif /* TW_OSL_DEBUG */
1109 break;
1110 } /* End of while */
1111
1112 /* Move commands from the reset queue to the pending queue. */
1113 while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_RESET_Q)) != TW_CL_NULL) {
1114 tw_osl_timeout(req->req_handle);
1115 tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
1116 }
1117
1116 }
1117
1118 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1119 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1120 0x1107, 0x3, TW_CL_SEVERITY_INFO_STRING,
1121 "Controller reset done!",
1122 " ");
1123
1124out:
1118 twa_setup_intr(sc);
1119 tw_cli_enable_interrupts(ctlr);
1120 if ((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL)
1121 TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
1122 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
1125 ctlr->reset_in_progress = TW_CL_FALSE;
1123 ctlr->reset_in_progress = TW_CL_FALSE;
1126 xpt_release_simq(sc->sim, 1);
1124 ctlr->reset_needed = TW_CL_FALSE;
1127
1125
1128 /*
1129 * Enable interrupts, and also clear attention and response interrupts.
1130 */
1131 tw_cli_enable_interrupts(ctlr);
1132
1133 /* Request for a bus re-scan. */
1126 /* Request for a bus re-scan. */
1134 if (!error)
1135 tw_osl_scan_bus(ctlr_handle);
1127 tw_osl_scan_bus(ctlr_handle);
1128
1136 return(error);
1137}
1138
1129 return(error);
1130}
1131
1132TW_VOID
1133tw_cl_set_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle)
1134{
1135 struct tw_cli_ctlr_context *ctlr =
1136 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
1139
1137
1138 ctlr->reset_needed = TW_CL_TRUE;
1139}
1140
1140
1141TW_INT32
1142tw_cl_is_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle)
1143{
1144 struct tw_cli_ctlr_context *ctlr =
1145 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
1146
1147 return(ctlr->reset_needed);
1148}
1149
1150TW_INT32
1151tw_cl_is_active(struct tw_cl_ctlr_handle *ctlr_handle)
1152{
1153 struct tw_cli_ctlr_context *ctlr =
1154 (struct tw_cli_ctlr_context *)
1155 (ctlr_handle->cl_ctlr_ctxt);
1156
1157 return(ctlr->active);
1158}
1159
1160
1161
1141/*
1142 * Function name: tw_cli_soft_reset
1143 * Description: Does the actual soft reset.
1144 *
1145 * Input: ctlr -- ptr to per ctlr structure
1146 * Output: None
1147 * Return value: 0 -- success
1148 * non-zero-- failure
1149 */
1150TW_INT32
1151tw_cli_soft_reset(struct tw_cli_ctlr_context *ctlr)
1152{
1153 struct tw_cl_ctlr_handle *ctlr_handle = ctlr->ctlr_handle;
1162/*
1163 * Function name: tw_cli_soft_reset
1164 * Description: Does the actual soft reset.
1165 *
1166 * Input: ctlr -- ptr to per ctlr structure
1167 * Output: None
1168 * Return value: 0 -- success
1169 * non-zero-- failure
1170 */
1171TW_INT32
1172tw_cli_soft_reset(struct tw_cli_ctlr_context *ctlr)
1173{
1174 struct tw_cl_ctlr_handle *ctlr_handle = ctlr->ctlr_handle;
1154 TW_UINT32 status_reg;
1155 int found;
1156 int loop_count;
1157 TW_UINT32 error;
1158
1159 tw_cli_dbg_printf(1, ctlr_handle, tw_osl_cur_func(), "entered");
1160
1175 int found;
1176 int loop_count;
1177 TW_UINT32 error;
1178
1179 tw_cli_dbg_printf(1, ctlr_handle, tw_osl_cur_func(), "entered");
1180
1161 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1181 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1162 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1163 0x1108, 0x3, TW_CL_SEVERITY_INFO_STRING,
1164 "Resetting controller...",
1165 " ");
1166
1167 /* Don't let any new commands get submitted to the controller. */
1168 tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
1169

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

1188 do {
1189 found = (tw_cli_find_response(ctlr, TWA_RESET_PHASE1_NOTIFICATION_RESPONSE) == TW_OSL_ESUCCESS);
1190 tw_osl_delay(10);
1191 loop_count++;
1192 error = 0x7888;
1193 } while (!found && (loop_count < 6000000)); /* Loop for no more than 60 seconds */
1194
1195 if (!found) {
1182 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1183 0x1108, 0x3, TW_CL_SEVERITY_INFO_STRING,
1184 "Resetting controller...",
1185 " ");
1186
1187 /* Don't let any new commands get submitted to the controller. */
1188 tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
1189

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

1208 do {
1209 found = (tw_cli_find_response(ctlr, TWA_RESET_PHASE1_NOTIFICATION_RESPONSE) == TW_OSL_ESUCCESS);
1210 tw_osl_delay(10);
1211 loop_count++;
1212 error = 0x7888;
1213 } while (!found && (loop_count < 6000000)); /* Loop for no more than 60 seconds */
1214
1215 if (!found) {
1196 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1216 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1197 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1198 0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1199 "Missed firmware handshake after soft-reset",
1200 "error = %d", error);
1201 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
1202 return(error);
1203 }
1204
1205 tw_osl_delay(TWA_RESET_PHASE1_WAIT_TIME_MS * 1000);
1206 ctlr->reset_phase1_in_progress = TW_CL_FALSE;
1207 }
1208
1209 if ((error = tw_cli_poll_status(ctlr,
1210 TWA_STATUS_MICROCONTROLLER_READY |
1211 TWA_STATUS_ATTENTION_INTERRUPT,
1212 TW_CLI_RESET_TIMEOUT_PERIOD))) {
1217 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1218 0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1219 "Missed firmware handshake after soft-reset",
1220 "error = %d", error);
1221 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
1222 return(error);
1223 }
1224
1225 tw_osl_delay(TWA_RESET_PHASE1_WAIT_TIME_MS * 1000);
1226 ctlr->reset_phase1_in_progress = TW_CL_FALSE;
1227 }
1228
1229 if ((error = tw_cli_poll_status(ctlr,
1230 TWA_STATUS_MICROCONTROLLER_READY |
1231 TWA_STATUS_ATTENTION_INTERRUPT,
1232 TW_CLI_RESET_TIMEOUT_PERIOD))) {
1213 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1233 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1214 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1215 0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1216 "Micro-ctlr not ready/No attn intr after reset",
1217 "error = %d", error);
1218 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
1219 return(error);
1220 }
1221

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

1239 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
1240 0x110B, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1241 "Can't drain AEN queue after reset",
1242 "error = %d", error);
1243 return(error);
1244 }
1245
1246 if ((error = tw_cli_find_aen(ctlr, TWA_AEN_SOFT_RESET))) {
1234 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1235 0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1236 "Micro-ctlr not ready/No attn intr after reset",
1237 "error = %d", error);
1238 tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
1239 return(error);
1240 }
1241

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

1259 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
1260 0x110B, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1261 "Can't drain AEN queue after reset",
1262 "error = %d", error);
1263 return(error);
1264 }
1265
1266 if ((error = tw_cli_find_aen(ctlr, TWA_AEN_SOFT_RESET))) {
1247 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1267 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
1248 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1249 0x110C, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1250 "Reset not reported by controller",
1251 "error = %d", error);
1252 return(error);
1253 }
1268 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1269 0x110C, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1270 "Reset not reported by controller",
1271 "error = %d", error);
1272 return(error);
1273 }
1254
1255 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
1256
1257 if ((error = TW_CLI_STATUS_ERRORS(status_reg)) ||
1258 (error = tw_cli_check_ctlr_state(ctlr, status_reg))) {
1259 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
1260 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
1261 0x110D, 0x1, TW_CL_SEVERITY_ERROR_STRING,
1262 "Controller errors detected after reset",
1263 "error = %d", error);
1264 return(error);
1265 }
1266
1274
1267 return(TW_OSL_ESUCCESS);
1268}
1269
1270
1271
1272/*
1273 * Function name: tw_cli_send_scsi_cmd
1274 * Description: Sends down a scsi cmd to fw.

--- 157 unchanged lines hidden ---
1275 return(TW_OSL_ESUCCESS);
1276}
1277
1278
1279
1280/*
1281 * Function name: tw_cli_send_scsi_cmd
1282 * Description: Sends down a scsi cmd to fw.

--- 157 unchanged lines hidden ---