# HG changeset patch # Parent c4486d17c80e40d77d0772461422c79e9ebb2f95 diff -r c4486d17c80e -r 6d7802308b08 sys/cam/ata/ata_all.h --- a/sys/cam/ata/ata_all.h +++ b/sys/cam/ata/ata_all.h @@ -65,6 +65,34 @@ struct ata_cmd { u_int8_t control; }; +struct sata_cmd { + u_int8_t flags; /* ATA command flags */ +/* see CAM_ATAIO_xxxx above */ + u_int8_t len; /* Length of initialized structure */ + + u_int8_t command; + u_int8_t features; + + u_int8_t lba_low; + u_int8_t lba_mid; + u_int8_t lba_high; + u_int8_t device; + + u_int8_t lba_low_exp; + u_int8_t lba_mid_exp; + u_int8_t lba_high_exp; + u_int8_t features_exp; + + u_int8_t sector_count; + u_int8_t sector_count_exp; + u_int8_t control; + + u_int8_t aux_low; /* Auxiliary register from standard */ + u_int8_t aux_lmid; + u_int8_t aux_hmid; + u_int8_t aux_high; +}; + struct ata_res { u_int8_t flags; /* ATA command flags */ #define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */ diff -r c4486d17c80e -r 6d7802308b08 sys/cam/ata/ata_da.c --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -87,7 +87,8 @@ typedef enum { ADA_FLAG_CAN_CFA = 0x0400, ADA_FLAG_CAN_POWERMGT = 0x0800, ADA_FLAG_CAN_DMA48 = 0x1000, - ADA_FLAG_DIRTY = 0x2000 + ADA_FLAG_DIRTY = 0x2000, + ADA_FLAG_CAN_NCQ_TRIM = 0x4000 } ada_flags; typedef enum { @@ -1178,6 +1179,7 @@ adaregister(struct cam_periph *periph, v softc->flags |= ADA_FLAG_CAN_NCQ; if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) && (cgd->inq_flags & SID_DMA)) { + /* XXX check here to see if it can NCQ trim */ softc->flags |= ADA_FLAG_CAN_TRIM; softc->trim_max_ranges = TRIM_MAX_RANGES; if (cgd->ident_data.max_dsm_blocks != 0) { @@ -1459,9 +1461,13 @@ ada_dsmtrim(struct ada_softc *softc, str ((ranges + ATA_DSM_BLK_RANGES - 1) / ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE, ada_default_timeout * 1000); - ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT, - ATA_DSM_TRIM, 0, (ranges + ATA_DSM_BLK_RANGES - - 1) / ATA_DSM_BLK_RANGES); + if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) { + ata_ncq_cmd(ataio, ATA_SEND_FPDMA_QUEUED, + 0, ATA_SFPDMA_DSM); + } else + ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT, + ATA_DSM_TRIM, 0, (ranges + ATA_DSM_BLK_RANGES - + 1) / ATA_DSM_BLK_RANGES); } static void diff -r c4486d17c80e -r 6d7802308b08 sys/cam/cam_ccb.h --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -188,6 +188,9 @@ typedef enum { * Get SIM specific knob values. */ + XPT_SATA_IO = 0x19 | XPT_FC_DEV_QUEUED, + /* Execute the requested SATA I/O operation */ + XPT_SET_SIM_KNOB = 0x19, /* * Set SIM specific knob values. @@ -739,6 +742,28 @@ struct ccb_ataio { u_int init_id; /* initiator id of who selected */ }; +/* + * SATA I/O Request CCB used for the XPT_SATA_IO function code. + */ +struct ccb_ataio { + struct ccb_hdr ccb_h; + union ccb *next_ccb; /* Ptr for next CCB for action */ + struct sata_cmd cmd; /* SATA command register set */ + struct ata_res res; /* ATA result register set (SATA doesn't expand) */ + 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 */ @@ -1295,6 +1320,23 @@ cam_fill_ataio(struct ccb_ataio *ataio, } static __inline void +cam_fill_sataio(struct ccb_sataio *sataio, 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) +{ + sataio->ccb_h.func_code = XPT_SATA_IO; + sataio->ccb_h.flags = flags; + sataio->ccb_h.retry_count = retries; + sataio->ccb_h.cbfcnp = cbfcnp; + sataio->ccb_h.timeout = timeout; + sataio->data_ptr = data_ptr; + sataio->dxfer_len = dxfer_len; + sataio->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 c4486d17c80e -r 6d7802308b08 sys/sys/ata.h --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -372,6 +372,10 @@ struct ata_params { #define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */ #define ATA_NCQ_NON_DATA 0x63 /* NCQ non-data command */ #define ATA_SEND_FPDMA_QUEUED 0x64 /* send DMA NCQ */ +#define ATA_SFPDMA_DSM 0x00 /* Data set management */ +#define ATA_SFPDMA_DSM_TRIM 0x01 /* Set trim bit in auxilary */ +#define ATA_SFPDMA_HYBRID_EVICT 0x01 /* Hybrid Evict */ +#define ATA_SFPDMA_WLDMA 0x02 /* Write Log DMA EXT */ #define ATA_RECV_FPDMA_QUEUED 0x65 /* recieve DMA NCQ */ #define ATA_SEP_ATTN 0x67 /* SEP request */ #define ATA_SEEK 0x70 /* seek */