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