# HG changeset patch # Parent 256a83a960ce84da47c9cbb4113a26fdf25da428 Data types for new FIS message. Periphs can now send raw FIS messages down to the SIMS. Include routines to fill them in, ala all the other commands. diff -r 256a83a960ce sys/cam/cam.c --- a/sys/cam/cam.c +++ b/sys/cam/cam.c @@ -248,6 +248,7 @@ cam_error_string(struct cam_device *devi return(NULL); switch (ccb->ccb_h.func_code) { + case XPT_SATA_FIS_IO: case XPT_ATA_IO: switch (proto_flags & CAM_EPF_LEVEL_MASK) { case CAM_EPF_NONE: @@ -325,6 +326,9 @@ cam_error_string(struct cam_device *devi CAM_ESMF_PRINT_FULL_CMD) ? 79 : 0); sbuf_printf(&sb, "\n"); break; + case XPT_SATA_FIS_IO: + // sata_fis_io_command_sbuf(&ccb->satafisio, &sb); + sbuf_printf(&sb, "FIS command not decoded\n"); default: break; } @@ -404,6 +408,22 @@ cam_error_string(struct cam_device *devi } /* There is no SMP equivalent to SCSI sense. */ break; + case XPT_SATA_FIS_IO: + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != + CAM_ATA_STATUS_ERROR) + break; + if (proto_flags & CAM_EAF_PRINT_STATUS) { + sbuf_cat(&sb, path_str); + /* ata_status_sbuf(&ccb->ataio, &sb); */ + sbuf_printf(&sb, "FIS STATUS BUF HERE\n"); + } + if (proto_flags & CAM_EAF_PRINT_RESULT) { + sbuf_cat(&sb, path_str); + /* ata_res_sbuf(&ccb->ataio, &sb); */ + sbuf_printf(&sb, "FIS RES BUF HERE\n"); + } + + break; default: break; } diff -r 256a83a960ce sys/cam/cam_ccb.h --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -1,3 +1,4 @@ + /*- * Data structures and definitions for CAM Control Blocks (CCBs). * @@ -188,6 +189,9 @@ typedef enum { * Get SIM specific knob values. */ + XPT_SATA_FIS_IO = 0x19 | XPT_FC_DEV_QUEUED, + /* Execute the requested ATA I/O operation */ + XPT_SET_SIM_KNOB = 0x19, /* * Set SIM specific knob values. @@ -739,6 +743,34 @@ struct ccb_ataio { u_int init_id; /* initiator id of who selected */ }; +/* + * SATA I/O Request CCB for raw FIS XPT_SATA_FIS_IO function code. + */ +#define CCB_SATAFISLEN (4 * 32) /* Amount of FIS data we automatically allocate */ +struct ccb_satafisio { + struct ccb_hdr ccb_h; + union ccb *next_ccb; /* Ptr for next CCB for action */ + u_int32_t flags; + u_int32_t fis_cmd_len; /* Length of FIS in DWORDS to send */ + u_int32_t fis_rep_len; /* Length of FIS reply in DWORDS */ + u_int8_t fis_cmd_buf[CCB_SATAFISLEN]; /* Raw FIS to send */ + u_int8_t fis_rep_buf[CCB_SATAFISLEN]; /* Raw FIS reply */ + u_int8_t *fis_cmd; /* Pointer to RAW FIS command */ + u_int8_t *fis_rep; /* Pointer to RAW FIS reply */ + u_int8_t *data_ptr; /* Ptr to the data buf/SG list */ + u_int32_t dxfer_len; /* Data transfer length */ + u_int32_t resid; /* Transfer residual length: 2's comp */ + u_int8_t tag_action; /* What to do for tag queueing */ + /* + * The tag action should be either the define below (to send a + * non-tagged transaction) or one of the defined scsi tag messages + * from scsi_message.h. + */ +#define CAM_TAG_ACTION_NONE 0x00 + u_int tag_id; /* tag id from initator (target mode) */ + u_int init_id; /* initiator id of who selected */ +}; + struct ccb_accept_tio { struct ccb_hdr ccb_h; cdb_t cdb_io; /* Union for CDB bytes/pointer */ @@ -1201,6 +1233,7 @@ union ccb { struct ccb_rescan crcn; struct ccb_debug cdbg; struct ccb_ataio ataio; + struct ccb_satafisio satafisio; struct ccb_dev_advinfo cdai; struct ccb_async casync; }; @@ -1229,6 +1262,13 @@ cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t timeout); static __inline void +cam_fill_satafisio(struct ccb_satafisio *satafisio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int32_t flags, u_int tag_action, + u_int8_t *data_ptr, u_int32_t dxfer_len, + u_int32_t timeout); + +static __inline void cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint8_t *smp_request, int smp_request_len, @@ -1295,6 +1335,28 @@ cam_fill_ataio(struct ccb_ataio *ataio, } static __inline void +cam_fill_satafisio(struct ccb_satafisio *satafisio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int32_t flags, u_int tag_action, + u_int8_t *data_ptr, u_int32_t dxfer_len, + u_int32_t timeout) +{ + satafisio->ccb_h.func_code = XPT_SATA_FIS_IO; + satafisio->ccb_h.flags = flags; + satafisio->ccb_h.retry_count = retries; + satafisio->ccb_h.cbfcnp = cbfcnp; + satafisio->ccb_h.timeout = timeout; + satafisio->flags = 0; + satafisio->fis_cmd = satafisio->fis_cmd_buf; + satafisio->fis_rep = satafisio->fis_rep_buf; + satafisio->fis_cmd_len = CCB_SATAFISLEN / 4; + satafisio->fis_rep_len = CCB_SATAFISLEN / 4; + satafisio->data_ptr = data_ptr; + satafisio->dxfer_len = dxfer_len; + satafisio->tag_action = tag_action; +} + +static __inline void cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint8_t *smp_request, int smp_request_len, diff -r 256a83a960ce sys/cam/cam_periph.c --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -763,6 +763,16 @@ cam_periph_mapmem(union ccb *ccb, struct dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; numbufs = 1; break; + case XPT_SATA_FIS_IO: + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) + return(0); + if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) + return (EINVAL); + data_ptrs[0] = &ccb->satafisio.data_ptr; + lengths[0] = ccb->satafisio.dxfer_len; + dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; + numbufs = 1; + break; case XPT_SMP_IO: data_ptrs[0] = &ccb->smpio.smp_request; lengths[0] = ccb->smpio.smp_request_len; @@ -929,6 +939,10 @@ cam_periph_unmapmem(union ccb *ccb, stru data_ptrs[0] = &ccb->ataio.data_ptr; numbufs = min(mapinfo->num_bufs_used, 1); break; + case XPT_SATA_FIS_IO: + data_ptrs[0] = &ccb->satafisio.data_ptr; + numbufs = min(mapinfo->num_bufs_used, 1); + break; case XPT_SMP_IO: numbufs = min(mapinfo->num_bufs_used, 2); data_ptrs[0] = &ccb->smpio.smp_request; @@ -1057,7 +1071,8 @@ cam_periph_runccb(union ccb *ccb, * this particular type of ccb, record the transaction start. */ if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO || - ccb->ccb_h.func_code == XPT_ATA_IO)) + ccb->ccb_h.func_code == XPT_ATA_IO || + ccb->ccb_h.func_code == XPT_SATA_FIS_IO)) devstat_start_transaction(ds, NULL); ccb->ccb_h.cbfcnp = cam_periph_done; @@ -1102,6 +1117,15 @@ cam_periph_runccb(union ccb *ccb, (ccb->ccb_h.flags & CAM_DIR_OUT) ? DEVSTAT_WRITE : DEVSTAT_READ, NULL, NULL); + } else if (ccb->ccb_h.func_code == XPT_SATA_FIS_IO) { + devstat_end_transaction(ds, + ccb->satafisio.dxfer_len, + ccb->satafisio.tag_action & 0x3, + ((ccb->ccb_h.flags & CAM_DIR_MASK) == + CAM_DIR_NONE) ? DEVSTAT_NO_DATA : + (ccb->ccb_h.flags & CAM_DIR_OUT) ? + DEVSTAT_WRITE : + DEVSTAT_READ, NULL, NULL); } } diff -r 256a83a960ce sys/cam/cam_xpt.c --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -2490,9 +2490,12 @@ xpt_action_default(union ccb *start_ccb) start_ccb->csio.sense_resid = 0; start_ccb->csio.resid = 0; /* FALLTHROUGH */ + case XPT_SATA_FIS_IO: case XPT_ATA_IO: if (start_ccb->ccb_h.func_code == XPT_ATA_IO) start_ccb->ataio.resid = 0; + if (start_ccb->ccb_h.func_code == XPT_SATA_FIS_IO) + start_ccb->satafisio.resid = 0; /* FALLTHROUGH */ case XPT_RESET_DEV: case XPT_ENG_EXEC: @@ -3275,6 +3278,10 @@ xpt_run_devq(struct cam_devq *devq) ata_cmd_string(&work_ccb->ataio.cmd, cdb_str, sizeof(cdb_str)))); break; + case XPT_SATA_FIS_IO: + CAM_DEBUG(work_ccb->ccb_h.path, + CAM_DEBUG_CDB,("FIS command: \n")); + break; default: break; } diff -r 256a83a960ce sys/kern/subr_bus_dma.c --- a/sys/kern/subr_bus_dma.c +++ b/sys/kern/subr_bus_dma.c @@ -201,6 +201,15 @@ static int sglist_cnt = 0; break; } + case XPT_SATA_FIS_IO: { + struct ccb_satafisio *satafisio; + + satafisio = &ccb->satafisio; + data_ptr = satafisio->data_ptr; + dxfer_len = satafisio->dxfer_len; + sglist_cnt = 0; + break; + } default: panic("_bus_dmamap_load_ccb: Unsupported func code %d", ccb_h->func_code);