Deleted Added
sdiff udiff text old ( 208969 ) 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_osl_cam.c 208969 2010-06-09 21:40:38Z 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);
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 */
84 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_REQUESTS)) == 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;
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 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
309 ccb_h->timeout_ch = timeout(twa_timeout, req,
310 (ccb_h->timeout * hz) / 1000);
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);
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 */
348 ccb_h->status |= CAM_REQUEUE_REQ;
349 xpt_done(ccb);
350 break;
351 }
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:
367 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
368 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
369 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
370 "Received Reset Bus request from CAM",
371 " ");
372
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);
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;
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/*
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/*
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.
580 *
581 * Input: ctlr_handle -- ptr to controller handle
582 * req_handle -- ptr to request handle sent by OSL.
583 * Output: None
584 * Return value: None
585 */
586TW_VOID
587tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle,
588 struct tw_cl_req_handle *req_handle)
589{
590 tw_osli_disallow_new_requests(ctlr_handle->osl_ctlr_ctxt, req_handle);
591}
592
593
594
595/*
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
658 untimeout(twa_timeout, req, ccb->ccb_h.timeout_ch);
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)
685 ccb->ccb_h.status |= 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 ---