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

--- 14 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);
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

--- 14 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);
58static TW_VOID twa_timeout(TW_VOID *arg);
59
60static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
61 union ccb *ccb);
62
63
64
65/*
66 * Function name: tw_osli_cam_attach

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

76{
77 struct cam_devq *devq;
78
79 tw_osli_dbg_dprintf(3, sc, "entered");
80
81 /*
82 * Create the device queue for our SIM.
83 */
58
59static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
60 union ccb *ccb);
61
62
63
64/*
65 * Function name: tw_osli_cam_attach

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

75{
76 struct cam_devq *devq;
77
78 tw_osli_dbg_dprintf(3, sc, "entered");
79
80 /*
81 * Create the device queue for our SIM.
82 */
84 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_REQUESTS)) == NULL) {
83 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {
85 tw_osli_printf(sc, "error = %d",
86 TW_CL_SEVERITY_ERROR_STRING,
87 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
88 0x2100,
89 "Failed to create SIM device queue",
90 ENOMEM);
91 return(ENOMEM);
92 }

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

270 if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) {
271 tw_osli_printf(sc, "size = %d",
272 TW_CL_SEVERITY_ERROR_STRING,
273 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
274 0x2106,
275 "I/O size too big",
276 csio->dxfer_len);
277 ccb_h->status = CAM_REQ_TOO_BIG;
84 tw_osli_printf(sc, "error = %d",
85 TW_CL_SEVERITY_ERROR_STRING,
86 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
87 0x2100,
88 "Failed to create SIM device queue",
89 ENOMEM);
90 return(ENOMEM);
91 }

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

269 if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) {
270 tw_osli_printf(sc, "size = %d",
271 TW_CL_SEVERITY_ERROR_STRING,
272 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
273 0x2106,
274 "I/O size too big",
275 csio->dxfer_len);
276 ccb_h->status = CAM_REQ_TOO_BIG;
277 ccb_h->status &= ~CAM_SIM_QUEUED;
278 xpt_done(ccb);
279 return(1);
280 }
281
282 if ((req->length = csio->dxfer_len)) {
283 req->data = csio->data_ptr;
284 scsi_req->sgl_entries = 1;
285 }
286 } else {
287 tw_osli_printf(sc, "",
288 TW_CL_SEVERITY_ERROR_STRING,
289 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
290 0x2107,
291 "XPT_SCSI_IO: Got SGList");
292 ccb_h->status = CAM_REQ_INVALID;
278 xpt_done(ccb);
279 return(1);
280 }
281
282 if ((req->length = csio->dxfer_len)) {
283 req->data = csio->data_ptr;
284 scsi_req->sgl_entries = 1;
285 }
286 } else {
287 tw_osli_printf(sc, "",
288 TW_CL_SEVERITY_ERROR_STRING,
289 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
290 0x2107,
291 "XPT_SCSI_IO: Got SGList");
292 ccb_h->status = CAM_REQ_INVALID;
293 ccb_h->status &= ~CAM_SIM_QUEUED;
293 xpt_done(ccb);
294 return(1);
295 }
296 } else {
297 /* Data addresses are physical. */
298 tw_osli_printf(sc, "",
299 TW_CL_SEVERITY_ERROR_STRING,
300 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
301 0x2108,
302 "XPT_SCSI_IO: Physical data addresses");
303 ccb_h->status = CAM_REQ_INVALID;
304 ccb_h->status &= ~CAM_SIM_QUEUED;
305 xpt_done(ccb);
306 return(1);
307 }
308
294 xpt_done(ccb);
295 return(1);
296 }
297 } else {
298 /* Data addresses are physical. */
299 tw_osli_printf(sc, "",
300 TW_CL_SEVERITY_ERROR_STRING,
301 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
302 0x2108,
303 "XPT_SCSI_IO: Physical data addresses");
304 ccb_h->status = CAM_REQ_INVALID;
305 ccb_h->status &= ~CAM_SIM_QUEUED;
306 xpt_done(ccb);
307 return(1);
308 }
309
309 ccb_h->timeout_ch = timeout(twa_timeout, req,
310 (ccb_h->timeout * hz) / 1000);
310 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);
311
312
311 /*
312 * twa_map_load_data_callback will fill in the SGL,
313 * and submit the I/O.
314 */
315 error = tw_osli_map_request(req);
313 /*
314 * twa_map_load_data_callback will fill in the SGL,
315 * and submit the I/O.
316 */
317 error = tw_osli_map_request(req);
318 if ((error) && (req->flags & TW_OSLI_REQ_FLAGS_FAILED)) {
319 req->deadline = 0;
320 ccb_h->status = CAM_REQ_CMP_ERR;
321 ccb_h->status &= ~CAM_SIM_QUEUED;
322 xpt_done(ccb);
323 }
316 return(error);
317}
318
319
320
321/*
322 * Function name: twa_action
323 * Description: Driver entry point for CAM's use.

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

340
341 req = tw_osli_get_request(sc);
342 if (req == NULL) {
343 tw_osli_dbg_dprintf(2, sc, "Cannot get request pkt.");
344 /*
345 * Freeze the simq to maintain ccb ordering. The next
346 * ccb that gets completed will unfreeze the simq.
347 */
324 return(error);
325}
326
327
328
329/*
330 * Function name: twa_action
331 * Description: Driver entry point for CAM's use.

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

348
349 req = tw_osli_get_request(sc);
350 if (req == NULL) {
351 tw_osli_dbg_dprintf(2, sc, "Cannot get request pkt.");
352 /*
353 * Freeze the simq to maintain ccb ordering. The next
354 * ccb that gets completed will unfreeze the simq.
355 */
356 ccb_h->status &= ~CAM_SIM_QUEUED;
348 ccb_h->status |= CAM_REQUEUE_REQ;
349 xpt_done(ccb);
350 break;
351 }
357 ccb_h->status |= CAM_REQUEUE_REQ;
358 xpt_done(ccb);
359 break;
360 }
361
362 if ((tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) {
363 ccb_h->status &= ~CAM_SIM_QUEUED;
364 ccb_h->status |= CAM_REQUEUE_REQ;
365 xpt_done(ccb);
366 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
367 break;
368 }
369
352 req->req_handle.osl_req_ctxt = req;
353 req->req_handle.is_io = TW_CL_TRUE;
354 req->orig_req = ccb;
355 if (tw_osli_execute_scsi(req, ccb))
356 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
357 break;
358 }
359
360 case XPT_ABORT:
361 tw_osli_dbg_dprintf(2, sc, "Abort request.");
362 ccb_h->status = CAM_UA_ABORT;
363 xpt_done(ccb);
364 break;
365
366 case XPT_RESET_BUS:
370 req->req_handle.osl_req_ctxt = req;
371 req->req_handle.is_io = TW_CL_TRUE;
372 req->orig_req = ccb;
373 if (tw_osli_execute_scsi(req, ccb))
374 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
375 break;
376 }
377
378 case XPT_ABORT:
379 tw_osli_dbg_dprintf(2, sc, "Abort request.");
380 ccb_h->status = CAM_UA_ABORT;
381 xpt_done(ccb);
382 break;
383
384 case XPT_RESET_BUS:
367 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
385 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_FALSE,
368 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
369 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
370 "Received Reset Bus request from CAM",
371 " ");
372
386 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
387 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
388 "Received Reset Bus request from CAM",
389 " ");
390
373 mtx_unlock(sc->sim_lock);
374 if (tw_cl_reset_ctlr(&sc->ctlr_handle)) {
375 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
376 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
377 0x2109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
378 "Failed to reset bus",
379 " ");
380 ccb_h->status = CAM_REQ_CMP_ERR;
381 }
382 else
383 ccb_h->status = CAM_REQ_CMP;
384
385 mtx_lock(sc->sim_lock);
391 tw_cl_set_reset_needed(&(sc->ctlr_handle));
392 ccb_h->status = CAM_REQ_CMP;
386 xpt_done(ccb);
387 break;
388
389 case XPT_SET_TRAN_SETTINGS:
390 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS");
391
392 /*
393 * This command is not supported, since it's very specific

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

445 path_inq->base_transfer_speed = 100000;
446 strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
447 strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
448 strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
449 path_inq->transport = XPORT_SPI;
450 path_inq->transport_version = 2;
451 path_inq->protocol = PROTO_SCSI;
452 path_inq->protocol_version = SCSI_REV_2;
393 xpt_done(ccb);
394 break;
395
396 case XPT_SET_TRAN_SETTINGS:
397 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS");
398
399 /*
400 * This command is not supported, since it's very specific

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

452 path_inq->base_transfer_speed = 100000;
453 strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
454 strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
455 strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
456 path_inq->transport = XPORT_SPI;
457 path_inq->transport_version = 2;
458 path_inq->protocol = PROTO_SCSI;
459 path_inq->protocol_version = SCSI_REV_2;
460 path_inq->maxio = TW_CL_MAX_IO_SIZE;
453 ccb_h->status = CAM_REQ_CMP;
454 xpt_done(ccb);
455 break;
456 }
457
458 default:
459 tw_osli_dbg_dprintf(3, sc, "func_code = %x", ccb_h->func_code);
460 ccb_h->status = CAM_REQ_INVALID;

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

482 tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc);
483 tw_cl_interrupt(&(sc->ctlr_handle));
484 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
485}
486
487
488
489/*
461 ccb_h->status = CAM_REQ_CMP;
462 xpt_done(ccb);
463 break;
464 }
465
466 default:
467 tw_osli_dbg_dprintf(3, sc, "func_code = %x", ccb_h->func_code);
468 ccb_h->status = CAM_REQ_INVALID;

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

490 tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc);
491 tw_cl_interrupt(&(sc->ctlr_handle));
492 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
493}
494
495
496
497/*
490 * Function name: twa_timeout
491 * Description: Driver entry point for being alerted on a request
492 * timing out.
493 *
494 * Input: arg -- ptr to timed out request
495 * Output: None
496 * Return value: None
497 */
498static TW_VOID
499twa_timeout(TW_VOID *arg)
500{
501 struct tw_osli_req_context *req =
502 (struct tw_osli_req_context *)arg;
503
504 tw_cl_create_event(&(req->ctlr->ctlr_handle), TW_CL_TRUE,
505 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
506 0x210B, 0x1, TW_CL_SEVERITY_ERROR_STRING,
507 "Request timed out!",
508 "request = %p", req);
509 tw_cl_reset_ctlr(&(req->ctlr->ctlr_handle));
510}
511
512
513
514/*
515 * Function name: tw_osli_request_bus_scan
516 * Description: Requests CAM for a scan of the bus.
517 *
518 * Input: sc -- ptr to per ctlr structure
519 * Output: None
520 * Return value: 0 -- success
521 * non-zero-- failure
522 */

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

569 xpt_freeze_simq(sc->sim, 1);
570 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
571 }
572}
573
574
575
576/*
498 * Function name: tw_osli_request_bus_scan
499 * Description: Requests CAM for a scan of the bus.
500 *
501 * Input: sc -- ptr to per ctlr structure
502 * Output: None
503 * Return value: 0 -- success
504 * non-zero-- failure
505 */

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

552 xpt_freeze_simq(sc->sim, 1);
553 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
554 }
555}
556
557
558
559/*
577 * Function name: tw_osl_ctlr_busy
578 * Description: CL calls this function on cmd queue full or otherwise,
579 * when it is too busy to accept new requests.
560 * Function name: tw_osl_timeout
561 * Description: Call to timeout().
580 *
562 *
581 * Input: ctlr_handle -- ptr to controller handle
582 * req_handle -- ptr to request handle sent by OSL.
563 * Input: req_handle -- ptr to request handle sent by OSL.
583 * Output: None
584 * Return value: None
585 */
586TW_VOID
564 * Output: None
565 * Return value: None
566 */
567TW_VOID
587tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle,
588 struct tw_cl_req_handle *req_handle)
568tw_osl_timeout(struct tw_cl_req_handle *req_handle)
589{
569{
590 tw_osli_disallow_new_requests(ctlr_handle->osl_ctlr_ctxt, req_handle);
570 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
571 union ccb *ccb = (union ccb *)(req->orig_req);
572 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
573
574 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);
591}
592
593
594
595/*
575}
576
577
578
579/*
580 * Function name: tw_osl_untimeout
581 * Description: Inverse of call to timeout().
582 *
583 * Input: req_handle -- ptr to request handle sent by OSL.
584 * Output: None
585 * Return value: None
586 */
587TW_VOID
588tw_osl_untimeout(struct tw_cl_req_handle *req_handle)
589{
590 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
591
592 req->deadline = 0;
593}
594
595
596
597/*
596 * Function name: tw_osl_scan_bus
597 * Description: CL calls this function to request for a bus scan.
598 *
599 * Input: ctlr_handle -- ptr to controller handle
600 * Output: None
601 * Return value: None
602 */
603TW_VOID

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

650 * There's no need to move it into the complete queue as we are
651 * going to be done with it right now.
652 */
653 req->state = TW_OSLI_REQ_STATE_COMPLETE;
654 tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q);
655
656 tw_osli_unmap_request(req);
657
598 * Function name: tw_osl_scan_bus
599 * Description: CL calls this function to request for a bus scan.
600 *
601 * Input: ctlr_handle -- ptr to controller handle
602 * Output: None
603 * Return value: None
604 */
605TW_VOID

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

652 * There's no need to move it into the complete queue as we are
653 * going to be done with it right now.
654 */
655 req->state = TW_OSLI_REQ_STATE_COMPLETE;
656 tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q);
657
658 tw_osli_unmap_request(req);
659
658 untimeout(twa_timeout, req, ccb->ccb_h.timeout_ch);
660 req->deadline = 0;
659 if (req->error_code) {
660 /* This request never got submitted to the firmware. */
661 if (req->error_code == EBUSY) {
662 /*
663 * Cmd queue is full, or the Common Layer is out of
664 * resources. The simq will already have been frozen.
665 * When this ccb gets completed will unfreeze the simq.
666 */

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

677 else {
678 if (req_pkt->status & TW_CL_ERR_REQ_INVALID_TARGET)
679 ccb->ccb_h.status |= CAM_TID_INVALID;
680 else if (req_pkt->status & TW_CL_ERR_REQ_INVALID_LUN)
681 ccb->ccb_h.status |= CAM_LUN_INVALID;
682 else if (req_pkt->status & TW_CL_ERR_REQ_SCSI_ERROR)
683 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
684 else if (req_pkt->status & TW_CL_ERR_REQ_BUS_RESET)
661 if (req->error_code) {
662 /* This request never got submitted to the firmware. */
663 if (req->error_code == EBUSY) {
664 /*
665 * Cmd queue is full, or the Common Layer is out of
666 * resources. The simq will already have been frozen.
667 * When this ccb gets completed will unfreeze the simq.
668 */

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

679 else {
680 if (req_pkt->status & TW_CL_ERR_REQ_INVALID_TARGET)
681 ccb->ccb_h.status |= CAM_TID_INVALID;
682 else if (req_pkt->status & TW_CL_ERR_REQ_INVALID_LUN)
683 ccb->ccb_h.status |= CAM_LUN_INVALID;
684 else if (req_pkt->status & TW_CL_ERR_REQ_SCSI_ERROR)
685 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
686 else if (req_pkt->status & TW_CL_ERR_REQ_BUS_RESET)
685 ccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
687 ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_SCSI_BUS_RESET);
686 /*
687 * If none of the above errors occurred, simply
688 * mark completion error.
689 */
690 if (ccb->ccb_h.status == 0)
691 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
692
693 if (req_pkt->status & TW_CL_ERR_REQ_AUTO_SENSE_VALID) {

--- 17 unchanged lines hidden ---
688 /*
689 * If none of the above errors occurred, simply
690 * mark completion error.
691 */
692 if (ccb->ccb_h.status == 0)
693 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
694
695 if (req_pkt->status & TW_CL_ERR_REQ_AUTO_SENSE_VALID) {

--- 17 unchanged lines hidden ---