Example #1
0
static int
ld_twa_dobio(struct ld_twa_softc *sc, void *data, size_t datasize,
	     daddr_t blkno, struct buf *bp)
{
	int rv;
	struct twa_request	*tr;
	struct twa_softc *twa;

	twa = device_private(device_parent(sc->sc_ld.sc_dv));

	if ((tr = twa_get_request(twa, 0)) == NULL) {
		return (EAGAIN);
	}
	if (bp->b_flags & B_READ) {
		tr->tr_flags = TWA_CMD_DATA_OUT;
	} else {
		tr->tr_flags = TWA_CMD_DATA_IN;
	}

	tr->tr_data = data;
	tr->tr_length = datasize;
	tr->tr_cmd_pkt_type =
		(TWA_CMD_PKT_TYPE_9K | TWA_CMD_PKT_TYPE_EXTERNAL);

	tr->tr_command->cmd_hdr.header_desc.size_header = 128;

	tr->tr_command->command.cmd_pkt_9k.command.opcode =
		TWA_OP_EXECUTE_SCSI_COMMAND;
	tr->tr_command->command.cmd_pkt_9k.unit =
		sc->sc_hwunit;
	tr->tr_command->command.cmd_pkt_9k.request_id =
		tr->tr_request_id;
	tr->tr_command->command.cmd_pkt_9k.status = 0;
	tr->tr_command->command.cmd_pkt_9k.sgl_entries = 1;
	tr->tr_command->command.cmd_pkt_9k.sgl_offset = 16;

	/* offset from end of hdr = max cdb len */
	ld_twa_scsicmd(sc, tr, bp);

	tr->tr_callback = ld_twa_handler;
	tr->tr_ld_sc = sc;

	tr->bp = bp;

	rv = twa_map_request(tr);

	return (rv);
}
Example #2
0
/*
 * Function name:	twa_action
 * Description:		Driver entry point for CAM's use.
 *
 * Input:		sim	-- sim corresponding to the ctlr
 *			ccb	-- ptr to CAM request
 * Output:		None
 * Return value:	None
 */
void
twa_action(struct cam_sim *sim, union ccb *ccb)
{
	struct twa_softc	*sc = (struct twa_softc *)cam_sim_softc(sim);
	struct ccb_hdr		*ccb_h = &(ccb->ccb_h);

	switch (ccb_h->func_code) {
	case XPT_SCSI_IO:	/* SCSI I/O */
	{
		struct twa_request	*tr;

		if ((sc->twa_state & TWA_STATE_SIMQ_FROZEN) ||
				((tr = twa_get_request(sc)) == NULL)) {
			twa_dbg_dprint(2, sc, "simq frozen/Cannot get request pkt.");
			/*
			 * Freeze the simq to maintain ccb ordering.  The next
			 * ccb that gets completed will unfreeze the simq.
			 */
			twa_disallow_new_requests(sc);
			ccb_h->status |= CAM_REQUEUE_REQ;
			xpt_done(ccb);
			break;
		}
		tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_EXTERNAL;
		tr->tr_private = ccb;
		tr->tr_callback = twa_complete_io;
		if (twa_execute_scsi(tr, ccb))
			twa_release_request(tr);
		break;
	}

	case XPT_ABORT:
		twa_dbg_dprint(2, sc, "Abort request");
		ccb_h->status = CAM_UA_ABORT;
		xpt_done(ccb);
		break;

	case XPT_RESET_BUS:
		twa_printf(sc, "Reset Bus request from CAM...\n");
		if (twa_reset(sc)) {
			twa_printf(sc, "Reset Bus failed!\n");
			ccb_h->status = CAM_REQ_CMP_ERR;
		}
		else
			ccb_h->status = CAM_REQ_CMP;

		xpt_done(ccb);
		break;

	case XPT_SET_TRAN_SETTINGS:
		twa_dbg_dprint(3, sc, "XPT_SET_TRAN_SETTINGS");

		/*
		 * This command is not supported, since it's very specific
		 * to SCSI, and we are doing ATA.
		 */
  		ccb_h->status = CAM_FUNC_NOTAVAIL;
  		xpt_done(ccb);
  		break;

	case XPT_GET_TRAN_SETTINGS: 
	{
		struct ccb_trans_settings	*cts = &ccb->cts;

		twa_dbg_dprint(3, sc, "XPT_GET_TRAN_SETTINGS");
		cts->valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID);
		cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
		ccb_h->status = CAM_REQ_CMP;
		xpt_done(ccb);
		break;
	}

	case XPT_CALC_GEOMETRY:
	{
		struct ccb_calc_geometry	*geom;

		twa_dbg_dprint(3, sc, "XPT_CALC_GEOMETRY request");
		geom = &ccb->ccg;

		if (geom->volume_size > 0x200000) /* 1 GB */ {
			geom->heads = 255;
			geom->secs_per_track = 63;
		} else {
			geom->heads = 64;
			geom->secs_per_track = 32;
		}
		geom->cylinders = geom->volume_size /
					(geom->heads * geom->secs_per_track);
		ccb_h->status = CAM_REQ_CMP;
		xpt_done(ccb);
		break;
	}

	case XPT_PATH_INQ:    /* Path inquiry -- get twa properties */
	{
		struct ccb_pathinq	*path_inq = &ccb->cpi;

		twa_dbg_dprint(3, sc, "XPT_PATH_INQ request");

		path_inq->version_num = 1;
		path_inq->hba_inquiry = 0;
		path_inq->target_sprt = 0;
		path_inq->hba_misc = 0;
		path_inq->hba_eng_cnt = 0;
		path_inq->max_target = TWA_MAX_UNITS;
		path_inq->max_lun = 0;
		path_inq->unit_number = cam_sim_unit(sim);
		path_inq->bus_id = cam_sim_bus(sim);
		path_inq->initiator_id = 12;
		path_inq->base_transfer_speed = 100000;
		strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
		strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
		strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
		ccb_h->status = CAM_REQ_CMP;
		xpt_done(ccb);
		break;
	}

	default:
		twa_dbg_dprint(3, sc, "func_code = %x", ccb_h->func_code);
		ccb_h->status = CAM_REQ_INVALID;
		xpt_done(ccb);
		break;
	}
}