Lines Matching +full:write +full:- +full:0 +full:- +full:bps
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
87 ADA_FLAG_CAN_48BIT = 0x00000002,
88 ADA_FLAG_CAN_FLUSHCACHE = 0x00000004,
89 ADA_FLAG_CAN_NCQ = 0x00000008,
90 ADA_FLAG_CAN_DMA = 0x00000010,
91 ADA_FLAG_NEED_OTAG = 0x00000020,
92 ADA_FLAG_WAS_OTAG = 0x00000040,
93 ADA_FLAG_CAN_TRIM = 0x00000080,
94 ADA_FLAG_OPEN = 0x00000100,
95 ADA_FLAG_SCTX_INIT = 0x00000200,
96 ADA_FLAG_CAN_CFA = 0x00000400,
97 ADA_FLAG_CAN_POWERMGT = 0x00000800,
98 ADA_FLAG_CAN_DMA48 = 0x00001000,
99 ADA_FLAG_CAN_LOG = 0x00002000,
100 ADA_FLAG_CAN_IDLOG = 0x00004000,
101 ADA_FLAG_CAN_SUPCAP = 0x00008000,
102 ADA_FLAG_CAN_ZONE = 0x00010000,
103 ADA_FLAG_CAN_WCACHE = 0x00020000,
104 ADA_FLAG_CAN_RAHEAD = 0x00040000,
105 ADA_FLAG_PROBED = 0x00080000,
106 ADA_FLAG_ANNOUNCED = 0x00100000,
107 ADA_FLAG_DIRTY = 0x00200000,
108 ADA_FLAG_CAN_NCQ_TRIM = 0x00400000, /* CAN_TRIM also set */
109 ADA_FLAG_PIM_ATA_EXT = 0x00800000,
110 ADA_FLAG_UNMAPPEDIO = 0x01000000,
111 ADA_FLAG_ROTATING = 0x02000000
142 ADA_Q_NONE = 0x00,
143 ADA_Q_4K = 0x01,
144 ADA_Q_NCQ_TRIM_BROKEN = 0x02,
145 ADA_Q_LOG_BROKEN = 0x04,
146 ADA_Q_SMR_DM = 0x08,
147 ADA_Q_NO_TRIM = 0x10,
148 ADA_Q_128KB = 0x20
161 ADA_CCB_RAHEAD = 0x01,
162 ADA_CCB_WCACHE = 0x02,
163 ADA_CCB_BUFFER_IO = 0x03,
164 ADA_CCB_DUMP = 0x05,
165 ADA_CCB_TRIM = 0x06,
166 ADA_CCB_LOGDIR = 0x07,
167 ADA_CCB_IDDIR = 0x08,
168 ADA_CCB_SUP_CAP = 0x09,
169 ADA_CCB_ZONE = 0x0a,
170 ADA_CCB_TYPE_MASK = 0x0F,
174 ADA_ZONE_NONE = 0x00,
175 ADA_ZONE_DRIVE_MANAGED = 0x01,
176 ADA_ZONE_HOST_AWARE = 0x02,
177 ADA_ZONE_HOST_MANAGED = 0x03
181 ADA_ZONE_FLAG_RZ_SUP = 0x0001,
182 ADA_ZONE_FLAG_OPEN_SUP = 0x0002,
183 ADA_ZONE_FLAG_CLOSE_SUP = 0x0004,
184 ADA_ZONE_FLAG_FINISH_SUP = 0x0008,
185 ADA_ZONE_FLAG_RWP_SUP = 0x0010,
191 ADA_ZONE_FLAG_URSWRZ = 0x0020,
192 ADA_ZONE_FLAG_OPT_SEQ_SET = 0x0040,
193 ADA_ZONE_FLAG_OPT_NONSEQ_SET = 0x0080,
194 ADA_ZONE_FLAG_MAX_SEQ_SET = 0x0100,
208 {ADA_ZONE_FLAG_RWP_SUP, "Reset Write Pointer" },
227 #if 0
244 TAILQ_HEAD(, bio) bps;
447 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair CSSD-F*", "*" },
479 { T_DIRECT, SIP_MEDIA_FIXED, "*", "M4-CT???M4SSD2*", "*" },
488 /*quirks*/0
519 { T_DIRECT, SIP_MEDIA_FIXED, "*", "C300-CTFDDAC???MAG*",
572 * Intel X25-M Series SSDs
616 /*quirks*/0
628 * Micron M5[15]0 SSDs
631 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M5[15]0*", "MU01" },
647 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY2*", "*" },
655 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY3*", "*" },
679 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX3*", "*" },
687 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX4*", "*" },
803 * SAMSUNG HD200HJ KF100-06
813 * SAMSUNG HD501LJ CR100-10
843 /*quirks*/0
912 #define ADA_RA (softc->read_ahead >= 0 ? \
913 softc->read_ahead : ada_read_ahead)
914 #define ADA_WC (softc->write_cache >= 0 ? \
915 softc->write_cache : ada_write_cache)
927 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
930 &ada_retry_count, 0, "Normal I/O retry count");
932 &ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
934 &ada_send_ordered, 0, "Send Ordered Tags");
936 &ada_spindown_shutdown, 0, "Spin down upon shutdown");
938 &ada_spindown_suspend, 0, "Spin down upon suspend");
940 &ada_read_ahead, 0, "Enable disk read-ahead");
942 &ada_write_cache, 0, "Enable disk write cache");
944 &ada_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
946 &ada_enable_uma_ccbs, 0, "Use UMA for CCBs");
967 TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0
983 periph = (struct cam_periph *)dp->d_drv1;
984 if (cam_periph_acquire(periph) != 0) {
989 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
995 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
998 softc = (struct ada_softc *)periph->softc;
999 softc->flags |= ADA_FLAG_OPEN;
1003 return (0);
1014 periph = (struct cam_periph *)dp->d_drv1;
1015 softc = (struct ada_softc *)periph->softc;
1018 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1022 if ((softc->flags & ADA_FLAG_DIRTY) != 0 &&
1023 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
1024 (periph->flags & CAM_PERIPH_INVALID) == 0 &&
1025 cam_periph_hold(periph, PRIBIO) == 0) {
1027 cam_fill_ataio(&ccb->ataio,
1031 0,
1033 0,
1036 if (softc->flags & ADA_FLAG_CAN_48BIT)
1037 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1039 ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
1040 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
1041 /*sense_flags*/0, softc->disk->d_devstat);
1043 if (error != 0)
1044 xpt_print(periph->path, "Synchronize cache failed\n");
1045 softc->flags &= ~ADA_FLAG_DIRTY;
1050 softc->flags &= ~ADA_FLAG_OPEN;
1052 while (softc->refcount != 0)
1053 cam_periph_sleep(periph, &softc->refcount, PRIBIO, "adaclose", 1);
1056 return (0);
1062 struct ada_softc *softc = (struct ada_softc *)periph->softc;
1064 if (softc->state != ADA_STATE_NORMAL)
1067 cam_iosched_schedule(softc->cam_iosched, periph);
1081 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1082 softc = (struct ada_softc *)periph->softc;
1086 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastrategy(%p)\n", bp));
1091 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
1102 if (bp->bio_cmd == BIO_ZONE)
1103 bp->bio_flags |= BIO_ORDERED;
1108 cam_iosched_queue_work(softc->cam_iosched, bp);
1129 int error = 0;
1132 periph = dp->d_drv1;
1133 softc = (struct ada_softc *)periph->softc;
1134 secsize = softc->params.secsize;
1137 if ((periph->flags & CAM_PERIPH_INVALID) != 0)
1140 memset(&ataio, 0, sizeof(ataio));
1141 if (length > 0) {
1142 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1145 0,
1148 0,
1152 if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
1156 0, lba, count);
1159 0, lba, count);
1162 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1163 if (error != 0)
1169 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
1170 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1179 0,
1182 0,
1184 0,
1187 if (softc->flags & ADA_FLAG_CAN_48BIT)
1188 ata_48bit_cmd(&ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1190 ata_28bit_cmd(&ataio, ATA_FLUSHCACHE, 0, 0, 0);
1192 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1193 if (error != 0)
1194 xpt_print(periph->path, "Synchronize cache failed\n");
1206 UMA_ALIGN_PTR, 0);
1216 "due to status 0x%x!\n", status);
1240 periph = (struct cam_periph *)dp->d_drv1;
1250 softc = (struct ada_softc *)periph->softc;
1253 * De-register any async callbacks.
1255 xpt_register_async(0, adaasync, periph, periph->path);
1257 softc->invalidations++;
1266 cam_iosched_flush(softc->cam_iosched, NULL, ENXIO);
1272 disk_gone(softc->disk);
1280 softc = (struct ada_softc *)periph->softc;
1284 cam_iosched_fini(softc->cam_iosched);
1289 if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0) {
1291 if (sysctl_ctx_free(&softc->sysctl_stats_ctx) != 0)
1292 xpt_print(periph->path,
1295 if (sysctl_ctx_free(&softc->sysctl_ctx) != 0)
1296 xpt_print(periph->path,
1300 disk_destroy(softc->disk);
1301 callout_drain(&softc->sendordered_c);
1310 if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
1311 softc->delete_method = ADA_DELETE_NCQ_DSM_TRIM;
1312 else if (softc->flags & ADA_FLAG_CAN_TRIM)
1313 softc->delete_method = ADA_DELETE_DSM_TRIM;
1314 else if ((softc->flags & ADA_FLAG_CAN_CFA) && !(softc->flags & ADA_FLAG_CAN_48BIT))
1315 softc->delete_method = ADA_DELETE_CFA_ERASE;
1317 softc->delete_method = ADA_DELETE_NONE;
1339 if (cgd->protocol != PROTO_ATA)
1356 "due to status 0x%x\n", status);
1361 softc = (struct ada_softc *)periph->softc;
1362 memset(&cgd, 0, sizeof(cgd));
1363 xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1372 disk_resize(softc->disk, M_NOWAIT);
1383 softc = periph->softc;
1384 disk_attr_changed(softc->disk, "GEOM::physpath",
1392 softc = (struct ada_softc *)periph->softc;
1393 if (softc->state != ADA_STATE_NORMAL)
1395 if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD)
1396 softc->state = ADA_STATE_RAHEAD;
1397 else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE)
1398 softc->state = ADA_STATE_WCACHE;
1399 else if ((softc->flags & ADA_FLAG_CAN_LOG)
1400 && (softc->zone_mode != ADA_ZONE_NONE))
1401 softc->state = ADA_STATE_LOGDIR;
1404 if (cam_periph_acquire(periph) != 0)
1405 softc->state = ADA_STATE_NORMAL;
1425 switch (softc->zone_mode) {
1457 sbuf_new_for_sysctl(&sb, NULL, 0, req);
1459 for (i = 0; i < sizeof(ada_zone_desc_table) /
1460 sizeof(ada_zone_desc_table[0]); i++) {
1461 if (softc->zone_flags & ada_zone_desc_table[i].value) {
1462 if (first == 0)
1465 first = 0;
1488 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
1493 softc = (struct ada_softc *)periph->softc;
1494 snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d",periph->unit_number);
1495 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
1497 sysctl_ctx_init(&softc->sysctl_ctx);
1498 softc->flags |= ADA_FLAG_SCTX_INIT;
1499 softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
1501 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, "device_index");
1502 if (softc->sysctl_tree == NULL) {
1508 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1511 softc, 0, adadeletemethodsysctl, "A",
1513 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1514 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1515 "trim_count", CTLFLAG_RD, &softc->trim_count,
1517 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1518 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1519 "trim_ranges", CTLFLAG_RD, &softc->trim_ranges,
1521 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1522 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1523 "trim_lbas", CTLFLAG_RD, &softc->trim_lbas,
1525 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1527 &softc->read_ahead, 0, "Enable disk read ahead.");
1528 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1530 &softc->write_cache, 0, "Enable disk write cache.");
1531 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1534 softc, 0, adazonemodesysctl, "A",
1536 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1539 softc, 0, adazonesupsysctl, "A",
1541 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1542 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1543 "optimal_seq_zones", CTLFLAG_RD, &softc->optimal_seq_zones,
1544 "Optimal Number of Open Sequential Write Preferred Zones");
1545 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1546 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1548 &softc->optimal_nonseq_zones,
1549 "Optimal Number of Non-Sequentially Written Sequential Write "
1551 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1552 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1553 "max_seq_zones", CTLFLAG_RD, &softc->max_seq_zones,
1554 "Maximum Number of Open Sequential Write Required Zones");
1555 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1557 softc, 0, adaflagssysctl, "A",
1559 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1561 &softc->flags, (u_int)ADA_FLAG_UNMAPPEDIO, adabitsysctl, "I",
1563 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1565 &softc->flags, (u_int)ADA_FLAG_ROTATING, adabitsysctl, "I",
1572 * whacking the next read or write.
1574 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1576 &softc->force_read_error, 0,
1578 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1580 &softc->force_write_error, 0,
1581 "Force a write error for the next N writes.");
1582 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1584 &softc->periodic_read_error, 0,
1586 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1588 periph, 0, cam_periph_invalidate_sysctl, "I",
1589 "Write 1 to invalidate the drive immediately");
1593 softc->sysctl_stats_tree = SYSCTL_ADD_NODE(&softc->sysctl_stats_ctx,
1594 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "stats",
1595 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Statistics");
1596 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1597 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1599 &softc->timeouts, 0,
1601 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1602 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1604 &softc->errors, 0,
1606 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1607 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1609 &softc->invalidations, 0,
1613 cam_iosched_sysctl_init(softc->cam_iosched, &softc->sysctl_ctx,
1614 softc->sysctl_tree);
1628 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1630 ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
1631 periph->path);
1633 if (ret == 0)
1634 bp->bio_completed = bp->bio_length;
1648 value = softc->delete_method;
1649 if (value < 0 || value > ADA_DELETE_MAX)
1655 if (error != 0 || req->newptr == NULL)
1658 if ((softc->flags & ADA_FLAG_CAN_CFA) &&
1659 !(softc->flags & ADA_FLAG_CAN_48BIT))
1661 if (softc->flags & ADA_FLAG_CAN_TRIM)
1663 if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
1665 for (i = 0; i <= ADA_DELETE_MAX; i++) {
1667 strcmp(buf, ada_delete_method_names[i]) != 0)
1669 softc->delete_method = i;
1670 return (0);
1684 if (error || !req->newptr)
1697 sbuf_new_for_sysctl(&sbuf, NULL, 0, req);
1698 if (softc->flags != 0)
1699 sbuf_printf(&sbuf, "0x%b", (unsigned)softc->flags, ADA_FLAG_STRING);
1701 sbuf_putc(&sbuf, '0');
1711 if ((cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
1712 (cgd->inq_flags & SID_DMA))
1713 softc->flags |= ADA_FLAG_CAN_DMA;
1715 softc->flags &= ~ADA_FLAG_CAN_DMA;
1717 if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) {
1718 softc->flags |= ADA_FLAG_CAN_48BIT;
1719 if (cgd->inq_flags & SID_DMA48)
1720 softc->flags |= ADA_FLAG_CAN_DMA48;
1722 softc->flags &= ~ADA_FLAG_CAN_DMA48;
1724 softc->flags &= ~(ADA_FLAG_CAN_48BIT | ADA_FLAG_CAN_DMA48);
1726 if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
1727 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
1729 softc->flags &= ~ADA_FLAG_CAN_FLUSHCACHE;
1731 if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
1732 softc->flags |= ADA_FLAG_CAN_POWERMGT;
1734 softc->flags &= ~ADA_FLAG_CAN_POWERMGT;
1736 if ((cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
1737 (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
1738 softc->flags |= ADA_FLAG_CAN_NCQ;
1740 softc->flags &= ~ADA_FLAG_CAN_NCQ;
1742 if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
1743 (cgd->inq_flags & SID_DMA) &&
1744 (softc->quirks & ADA_Q_NO_TRIM) == 0) {
1745 softc->flags |= ADA_FLAG_CAN_TRIM;
1746 softc->trim_max_ranges = TRIM_MAX_RANGES;
1747 if (cgd->ident_data.max_dsm_blocks != 0) {
1748 softc->trim_max_ranges =
1749 min(cgd->ident_data.max_dsm_blocks *
1750 ATA_DSM_BLK_RANGES, softc->trim_max_ranges);
1756 * should look at log 13 dword 0 bit 0 and dword 1 bit 0 are
1759 if ((softc->quirks & ADA_Q_NCQ_TRIM_BROKEN) == 0 &&
1760 (softc->flags & ADA_FLAG_PIM_ATA_EXT) != 0 &&
1761 (cgd->ident_data.satacapabilities2 &
1762 ATA_SUPPORT_RCVSND_FPDMA_QUEUED) != 0 &&
1763 (softc->flags & ADA_FLAG_CAN_TRIM) != 0)
1764 softc->flags |= ADA_FLAG_CAN_NCQ_TRIM;
1766 softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
1768 softc->flags &= ~(ADA_FLAG_CAN_TRIM | ADA_FLAG_CAN_NCQ_TRIM);
1770 if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
1771 softc->flags |= ADA_FLAG_CAN_CFA;
1773 softc->flags &= ~ADA_FLAG_CAN_CFA;
1781 if ((cgd->ident_data.support.extension & ATA_SUPPORT_GENLOG)
1782 && ((softc->quirks & ADA_Q_LOG_BROKEN) == 0))
1783 softc->flags |= ADA_FLAG_CAN_LOG;
1785 softc->flags &= ~ADA_FLAG_CAN_LOG;
1787 if ((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
1789 softc->zone_mode = ADA_ZONE_HOST_AWARE;
1790 else if (((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
1792 || (softc->quirks & ADA_Q_SMR_DM))
1793 softc->zone_mode = ADA_ZONE_DRIVE_MANAGED;
1795 softc->zone_mode = ADA_ZONE_NONE;
1797 if (cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD)
1798 softc->flags |= ADA_FLAG_CAN_RAHEAD;
1800 softc->flags &= ~ADA_FLAG_CAN_RAHEAD;
1802 if (cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE)
1803 softc->flags |= ADA_FLAG_CAN_WCACHE;
1805 softc->flags &= ~ADA_FLAG_CAN_WCACHE;
1834 announce_buf = softc->announce_temp;
1837 periph->softc = softc;
1838 xpt_path_inq(&softc->cpi, periph->path);
1843 match = cam_quirkmatch((caddr_t)&cgd->ident_data,
1848 softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
1850 softc->quirks = ADA_Q_NONE;
1852 TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
1862 "kern.cam.ada.%d.quirks", periph->unit_number);
1863 quirks = softc->quirks;
1865 softc->quirks = quirks;
1866 softc->read_ahead = -1;
1868 "kern.cam.ada.%d.read_ahead", periph->unit_number);
1869 TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead);
1870 softc->write_cache = -1;
1872 "kern.cam.ada.%d.write_cache", periph->unit_number);
1873 TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
1876 * Let XPT know we can use UMA-allocated CCBs.
1881 periph->ccb_zone = ada_ccb_zone;
1888 if (softc->cpi.hba_misc & PIM_ATA_EXT)
1889 softc->flags |= ADA_FLAG_PIM_ATA_EXT;
1891 /* Disable queue sorting for non-rotational media by default. */
1892 if (cgd->ident_data.media_rotation_rate == ATA_RATE_NON_ROTATING) {
1893 softc->flags &= ~ADA_FLAG_ROTATING;
1895 softc->flags |= ADA_FLAG_ROTATING;
1897 softc->disk = disk_alloc();
1899 softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
1900 periph->unit_number, softc->params.secsize,
1903 XPORT_DEVSTAT_TYPE(softc->cpi.transport),
1905 softc->disk->d_open = adaopen;
1906 softc->disk->d_close = adaclose;
1907 softc->disk->d_strategy = adastrategy;
1908 softc->disk->d_getattr = adagetattr;
1909 if (cam_sim_pollable(periph->sim))
1910 softc->disk->d_dump = adadump;
1911 softc->disk->d_gone = adadiskgonecb;
1912 softc->disk->d_name = "ada";
1913 softc->disk->d_drv1 = periph;
1914 softc->disk->d_unit = periph->unit_number;
1916 if (cam_iosched_init(&softc->cam_iosched, periph, softc->disk,
1917 adaschedule) != 0) {
1923 cam_iosched_set_sort_queue(softc->cam_iosched,
1924 (softc->flags & ADA_FLAG_ROTATING) ? -1 : 0);
1928 dp = &softc->params;
1931 ((uintmax_t)dp->secsize * dp->sectors) / (1024 * 1024),
1932 (uintmax_t)dp->sectors, dp->secsize);
1934 sbuf_new(&sb, softc->announce_buffer, ADA_ANNOUNCE_SZ, SBUF_FIXEDLEN);
1936 xpt_announce_quirks_sbuf(periph, &sb, softc->quirks, ADA_Q_BIT_STRING);
1944 if (cam_periph_acquire(periph) == 0)
1945 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
1957 adaasync, periph, periph->path);
1963 callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0);
1964 callout_reset_sbt(&softc->sendordered_c,
1965 SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
1971 if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD) {
1972 softc->state = ADA_STATE_RAHEAD;
1973 } else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE) {
1974 softc->state = ADA_STATE_WCACHE;
1975 } else if ((softc->flags & ADA_FLAG_CAN_LOG)
1976 && (softc->zone_mode != ADA_ZONE_NONE)) {
1977 softc->state = ADA_STATE_LOGDIR;
1994 uint64_t lastlba = (uint64_t)-1, lbas = 0;
1995 int c, lastcount = 0, off, ranges = 0;
1998 TAILQ_INIT(&req->bps);
2000 uint64_t lba = bp->bio_pblkno;
2001 int count = bp->bio_bcount / softc->params.secsize;
2005 c = min(count, ATA_DSM_RANGE_MAX - lastcount);
2007 off = (ranges - 1) * ATA_DSM_RANGE_SIZE;
2008 req->data[off + 6] = lastcount & 0xff;
2009 req->data[off + 7] =
2010 (lastcount >> 8) & 0xff;
2011 count -= c;
2016 while (count > 0) {
2019 req->data[off + 0] = lba & 0xff;
2020 req->data[off + 1] = (lba >> 8) & 0xff;
2021 req->data[off + 2] = (lba >> 16) & 0xff;
2022 req->data[off + 3] = (lba >> 24) & 0xff;
2023 req->data[off + 4] = (lba >> 32) & 0xff;
2024 req->data[off + 5] = (lba >> 40) & 0xff;
2025 req->data[off + 6] = c & 0xff;
2026 req->data[off + 7] = (c >> 8) & 0xff;
2029 count -= c;
2039 TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
2041 bp = cam_iosched_next_trim(softc->cam_iosched);
2044 if (bp->bio_bcount / softc->params.secsize >
2045 (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX) {
2046 cam_iosched_put_back_trim(softc->cam_iosched, bp);
2050 softc->trim_count++;
2051 softc->trim_ranges += ranges;
2052 softc->trim_lbas += lbas;
2060 struct trim_request *req = &softc->trim_req;
2068 0,
2069 req->data,
2073 ATA_DSM_TRIM, 0, howmany(ranges, ATA_DSM_BLK_RANGES));
2079 struct trim_request *req = &softc->trim_req;
2087 0,
2088 req->data,
2093 0,
2095 ataio->cmd.sector_count_exp = ATA_SFPDMA_DSM;
2096 ataio->ata_flags |= ATA_FLAG_AUX;
2097 ataio->aux = 1;
2103 struct trim_request *req = &softc->trim_req;
2104 uint64_t lba = bp->bio_pblkno;
2105 uint16_t count = bp->bio_bcount / softc->params.secsize;
2108 TAILQ_INIT(&req->bps);
2109 TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
2115 0,
2117 0,
2121 count = 0;
2122 ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
2139 return -1;
2149 error = 0;
2151 if (bp->bio_cmd != BIO_ZONE) {
2156 softc = periph->softc;
2158 switch (bp->bio_zone.zone_cmd) {
2167 zone_sa = ada_zone_bio_to_ata(bp->bio_zone.zone_cmd);
2168 if (zone_sa == -1) {
2169 xpt_print(periph->path, "Cannot translate zone "
2170 "cmd %#x to ATA\n", bp->bio_zone.zone_cmd);
2175 zone_flags = 0;
2176 lba = bp->bio_zone.zone_params.rwp.id;
2178 if (bp->bio_zone.zone_params.rwp.flags &
2182 ata_zac_mgmt_out(&ccb->ataio,
2185 /*use_ncq*/ (softc->flags &
2186 ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
2190 /*sector_count*/ 0,
2192 /*dxfer_len*/ 0,
2203 rep = &bp->bio_zone.zone_params.report;
2205 num_entries = rep->entries_allocated;
2206 if (num_entries == 0) {
2207 xpt_print(periph->path, "No entries allocated for "
2214 alloc_size = min(alloc_size, softc->disk->d_maxsize);
2217 xpt_print(periph->path, "Unable to allocate memory "
2223 ata_zac_mgmt_in(&ccb->ataio,
2226 /*use_ncq*/ (softc->flags &
2227 ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
2229 /*zone_id*/ rep->starting_id,
2230 /*zone_flags*/ rep->rep_options,
2242 * it. devstat uses bio_bcount - bio_resid to calculate
2244 * uses bio_length - bio_resid to calculate the amount of
2259 bp->bio_bcount = bp->bio_length;
2268 params = &bp->bio_zone.zone_params.disk_params;
2271 switch (softc->zone_mode) {
2273 params->zone_mode = DISK_ZONE_MODE_DRIVE_MANAGED;
2276 params->zone_mode = DISK_ZONE_MODE_HOST_AWARE;
2279 params->zone_mode = DISK_ZONE_MODE_HOST_MANAGED;
2283 params->zone_mode = DISK_ZONE_MODE_NONE;
2287 if (softc->zone_flags & ADA_ZONE_FLAG_URSWRZ)
2288 params->flags |= DISK_ZONE_DISK_URSWRZ;
2290 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_SEQ_SET) {
2291 params->optimal_seq_zones = softc->optimal_seq_zones;
2292 params->flags |= DISK_ZONE_OPT_SEQ_SET;
2295 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_NONSEQ_SET) {
2296 params->optimal_nonseq_zones =
2297 softc->optimal_nonseq_zones;
2298 params->flags |= DISK_ZONE_OPT_NONSEQ_SET;
2301 if (softc->zone_flags & ADA_ZONE_FLAG_MAX_SEQ_SET) {
2302 params->max_seq_zones = softc->max_seq_zones;
2303 params->flags |= DISK_ZONE_MAX_SEQ_SET;
2305 if (softc->zone_flags & ADA_ZONE_FLAG_RZ_SUP)
2306 params->flags |= DISK_ZONE_RZ_SUP;
2308 if (softc->zone_flags & ADA_ZONE_FLAG_OPEN_SUP)
2309 params->flags |= DISK_ZONE_OPEN_SUP;
2311 if (softc->zone_flags & ADA_ZONE_FLAG_CLOSE_SUP)
2312 params->flags |= DISK_ZONE_CLOSE_SUP;
2314 if (softc->zone_flags & ADA_ZONE_FLAG_FINISH_SUP)
2315 params->flags |= DISK_ZONE_FINISH_SUP;
2317 if (softc->zone_flags & ADA_ZONE_FLAG_RWP_SUP)
2318 params->flags |= DISK_ZONE_RWP_SUP;
2331 struct ada_softc *softc = (struct ada_softc *)periph->softc;
2332 struct ccb_ataio *ataio = &start_ccb->ataio;
2334 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
2336 switch (softc->state) {
2342 bp = cam_iosched_next_bio(softc->cam_iosched);
2348 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
2349 (bp->bio_cmd != BIO_DELETE && (softc->flags & ADA_FLAG_NEED_OTAG) != 0)) {
2350 softc->flags &= ~ADA_FLAG_NEED_OTAG;
2351 softc->flags |= ADA_FLAG_WAS_OTAG;
2352 tag_code = 0;
2356 switch (bp->bio_cmd) {
2360 uint64_t lba = bp->bio_pblkno;
2361 uint16_t count = bp->bio_bcount / softc->params.secsize;
2365 if (bp->bio_cmd == BIO_WRITE) {
2366 softc->flags |= ADA_FLAG_DIRTY;
2372 data_ptr = bp->bio_data;
2373 if ((bp->bio_flags & (BIO_UNMAPPED|BIO_VLIST)) != 0) {
2379 int fail = 0;
2384 * if a write and pending write errors, then fail this
2390 if (bp->bio_cmd == BIO_READ) {
2391 if (softc->force_read_error) {
2392 softc->force_read_error--;
2395 if (softc->periodic_read_error > 0) {
2396 if (++softc->periodic_read_count >=
2397 softc->periodic_read_error) {
2398 softc->periodic_read_count = 0;
2403 if (softc->force_write_error) {
2404 softc->force_write_error--;
2415 KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
2416 round_page(bp->bio_bcount + bp->bio_ma_offset) /
2417 PAGE_SIZE == bp->bio_ma_n,
2423 0,
2425 bp->bio_bcount,
2428 if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
2429 if (bp->bio_cmd == BIO_READ) {
2436 } else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
2439 if (softc->flags & ADA_FLAG_CAN_DMA48) {
2440 if (bp->bio_cmd == BIO_READ) {
2442 0, lba, count);
2445 0, lba, count);
2448 if (bp->bio_cmd == BIO_READ) {
2450 0, lba, count);
2453 0, lba, count);
2458 count = 0;
2459 if (softc->flags & ADA_FLAG_CAN_DMA) {
2460 if (bp->bio_cmd == BIO_READ) {
2462 0, lba, count);
2465 0, lba, count);
2468 if (bp->bio_cmd == BIO_READ) {
2470 0, lba, count);
2473 0, lba, count);
2480 switch (softc->delete_method) {
2496 start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
2497 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
2498 cam_iosched_submit_trim(softc->cam_iosched);
2505 0,
2507 0,
2510 if (softc->flags & ADA_FLAG_CAN_48BIT)
2511 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
2513 ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
2518 queue_ccb = 0;
2521 if ((error != 0)
2522 || (queue_ccb == 0)) {
2543 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
2544 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
2546 start_ccb->ccb_h.ccb_bp = bp;
2547 softc->outstanding_cmds++;
2548 softc->refcount++;
2564 0,
2566 0,
2569 if (softc->state == ADA_STATE_RAHEAD) {
2571 ATA_SF_ENAB_RCACHE : ATA_SF_DIS_RCACHE, 0, 0);
2572 start_ccb->ccb_h.ccb_state = ADA_CCB_RAHEAD;
2575 ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0);
2576 start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE;
2578 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
2586 if ((softc->flags & ADA_FLAG_CAN_LOG) == 0) {
2593 xpt_print(periph->path, "Couldn't malloc log_dir "
2595 softc->state = ADA_STATE_NORMAL;
2604 /*page_number*/ 0,
2606 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2607 CAM_ATAIO_DMA : 0,
2612 start_ccb->ccb_h.ccb_state = ADA_CCB_LOGDIR;
2622 xpt_print(periph->path, "Couldn't malloc id_dir "
2634 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2635 CAM_ATAIO_DMA : 0,
2640 start_ccb->ccb_h.ccb_state = ADA_CCB_IDDIR;
2650 xpt_print(periph->path, "Couldn't malloc sup_cap "
2662 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2663 CAM_ATAIO_DMA : 0,
2668 start_ccb->ccb_h.ccb_state = ADA_CCB_SUP_CAP;
2678 xpt_print(periph->path, "Couldn't malloc ata_zone "
2690 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2691 CAM_ATAIO_DMA : 0,
2696 start_ccb->ccb_h.ccb_state = ADA_CCB_ZONE;
2708 softc = (struct ada_softc *)periph->softc;
2719 softc->state = ADA_STATE_NORMAL;
2720 softc->flags |= ADA_FLAG_PROBED;
2722 if ((softc->flags & ADA_FLAG_ANNOUNCED) == 0) {
2723 softc->flags |= ADA_FLAG_ANNOUNCED;
2729 if (cam_periph_acquire(periph) == 0)
2730 disk_create(softc->disk, DISK_VERSION);
2742 bp = (struct bio *)ccb->ccb_h.ccb_bp;
2744 switch (bp->bio_zone.zone_cmd) {
2759 rep = &bp->bio_zone.zone_params.report;
2760 avail_len = ccb->ataio.dxfer_len - ccb->ataio.resid;
2771 hdr = (struct scsi_report_zones_hdr *)ccb->ataio.data_ptr;
2778 bp->bio_error = EIO;
2779 bp->bio_flags |= BIO_ERROR;
2780 bp->bio_resid = bp->bio_bcount;
2784 hdr_len = le32dec(hdr->length);
2785 if (hdr_len > 0)
2786 rep->entries_available = hdr_len / sizeof(*desc);
2788 rep->entries_available = 0;
2795 rep->header.same = hdr->byte4 & SRZ_SAME_MASK;
2796 rep->header.maximum_lba = le64dec(hdr->maximum_lba);
2801 if (hdr_len == 0) {
2802 rep->entries_filled = 0;
2803 bp->bio_resid = bp->bio_bcount;
2807 num_avail = min((avail_len - sizeof(*hdr)) / sizeof(*desc),
2812 if (num_avail == 0) {
2813 rep->entries_filled = 0;
2814 bp->bio_resid = bp->bio_bcount;
2818 num_to_fill = min(num_avail, rep->entries_allocated);
2823 if (num_to_fill == 0) {
2824 rep->entries_filled = 0;
2825 bp->bio_resid = bp->bio_bcount;
2829 for (i = 0, desc = &hdr->desc_list[0], entry=&rep->entries[0];
2840 entry->zone_type = desc->zone_type & SRZ_TYPE_MASK;
2841 entry->zone_condition =
2842 (desc->zone_flags & SRZ_ZONE_COND_MASK) >>
2844 entry->zone_flags |= desc->zone_flags &
2846 entry->zone_length = le64dec(desc->zone_length);
2847 entry->zone_start_lba = le64dec(desc->zone_start_lba);
2848 entry->write_pointer_lba =
2849 le64dec(desc->write_pointer_lba);
2851 rep->entries_filled = num_to_fill;
2858 bp->bio_resid = bp->bio_bcount - (num_to_fill * sizeof(*entry));
2869 bp->bio_zone.zone_cmd);
2873 if (bp->bio_zone.zone_cmd == DISK_ZONE_REPORT_ZONES)
2874 free(ccb->ataio.data_ptr, M_ATADA);
2886 softc = (struct ada_softc *)periph->softc;
2887 ataio = &done_ccb->ataio;
2888 path = done_ccb->ccb_h.path;
2889 priority = done_ccb->ccb_h.pinfo.priority;
2893 state = ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK;
2902 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2903 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2904 error = adaerror(done_ccb, CAM_RETRY_SELTO, 0);
2910 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2912 /*relsim_flags*/0,
2913 /*reduction*/0,
2914 /*timeout*/0,
2915 /*getcount_only*/0);
2918 * to a non-NCQ DSM TRIM forever. Please note that if
2924 error != 0 &&
2925 (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) != 0) {
2926 softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
2927 error = 0;
2931 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2934 error = 0;
2936 bp->bio_error = error;
2937 if (error != 0) {
2938 bp->bio_resid = bp->bio_bcount;
2939 bp->bio_flags |= BIO_ERROR;
2941 if (bp->bio_cmd == BIO_ZONE)
2944 bp->bio_resid = 0;
2946 bp->bio_resid = ataio->resid;
2948 if ((bp->bio_resid > 0)
2949 && (bp->bio_cmd != BIO_ZONE))
2950 bp->bio_flags |= BIO_ERROR;
2952 softc->outstanding_cmds--;
2953 if (softc->outstanding_cmds == 0)
2954 softc->flags |= ADA_FLAG_WAS_OTAG;
2963 cam_iosched_bio_complete(softc->cam_iosched, bp, done_ccb);
2965 KASSERT(softc->refcount >= 1, ("adadone softc %p refcount %d", softc, softc->refcount));
2966 softc->refcount--;
2972 TAILQ_CONCAT(&queue, &softc->trim_req.bps, bio_queue);
2977 * trim_running set to 0 before the call above to allow
2979 * are pushed down. We set trim_running to 0 and call
2983 cam_iosched_trim_done(softc->cam_iosched);
2988 bp1->bio_error = error;
2989 if (error != 0) {
2990 bp1->bio_flags |= BIO_ERROR;
2991 bp1->bio_resid = bp1->bio_bcount;
2993 bp1->bio_resid = 0;
3005 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3006 if (adaerror(done_ccb, 0, 0) == ERESTART) {
3008 cam_release_devq(path, 0, 0, 0, FALSE);
3010 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3012 /*relsim_flags*/0,
3013 /*reduction*/0,
3014 /*timeout*/0,
3015 /*getcount_only*/0);
3020 softc->state = ADA_STATE_WCACHE;
3023 cam_release_devq(path, 0, 0, 0, FALSE);
3028 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3029 if (adaerror(done_ccb, 0, 0) == ERESTART) {
3031 cam_release_devq(path, 0, 0, 0, FALSE);
3033 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3035 /*relsim_flags*/0,
3036 /*reduction*/0,
3037 /*timeout*/0,
3038 /*getcount_only*/0);
3043 cam_release_devq(path, 0, 0, 0, FALSE);
3045 if ((softc->flags & ADA_FLAG_CAN_LOG)
3046 && (softc->zone_mode != ADA_ZONE_NONE)) {
3048 softc->state = ADA_STATE_LOGDIR;
3059 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3060 error = 0;
3061 softc->valid_logdir_len = 0;
3062 bzero(&softc->ata_logdir, sizeof(softc->ata_logdir));
3063 softc->valid_logdir_len =
3064 ataio->dxfer_len - ataio->resid;
3065 if (softc->valid_logdir_len > 0)
3066 bcopy(ataio->data_ptr, &softc->ata_logdir,
3067 min(softc->valid_logdir_len,
3068 sizeof(softc->ata_logdir)));
3076 if ((softc->valid_logdir_len >=
3078 && (le16dec(softc->ata_logdir.header) ==
3080 && (le16dec(&softc->ata_logdir.num_pages[
3082 sizeof(uint16_t)) - sizeof(uint16_t)]) > 0)){
3083 softc->flags |= ADA_FLAG_CAN_IDLOG;
3085 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
3092 else if (error != 0) {
3099 softc->flags &= ~(ADA_FLAG_CAN_LOG |
3101 if ((done_ccb->ccb_h.status &
3102 CAM_DEV_QFRZN) != 0) {
3104 cam_release_devq(done_ccb->ccb_h.path,
3105 /*relsim_flags*/0,
3106 /*reduction*/0,
3107 /*timeout*/0,
3108 /*getcount_only*/0);
3113 free(ataio->data_ptr, M_ATADA);
3115 if ((error == 0)
3116 && (softc->flags & ADA_FLAG_CAN_IDLOG)) {
3117 softc->state = ADA_STATE_IDDIR;
3128 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3130 error = 0;
3132 softc->valid_iddir_len = 0;
3133 bzero(&softc->ata_iddir, sizeof(softc->ata_iddir));
3134 softc->flags &= ~(ADA_FLAG_CAN_SUPCAP |
3136 softc->valid_iddir_len =
3137 ataio->dxfer_len - ataio->resid;
3138 if (softc->valid_iddir_len > 0)
3139 bcopy(ataio->data_ptr, &softc->ata_iddir,
3140 min(softc->valid_iddir_len,
3141 sizeof(softc->ata_iddir)));
3145 max_entries = softc->valid_iddir_len - entries_offset;
3146 if ((softc->valid_iddir_len > (entries_offset + 1))
3147 && (le64dec(softc->ata_iddir.header) ==
3149 && (softc->ata_iddir.entry_count > 0)) {
3152 num_entries = softc->ata_iddir.entry_count;
3154 softc->valid_iddir_len - entries_offset);
3155 for (i = 0; i < num_entries &&
3157 if (softc->ata_iddir.entries[i] ==
3159 softc->flags |=
3161 else if (softc->ata_iddir.entries[i]==
3163 softc->flags |=
3166 if ((softc->flags &
3168 && (softc->flags &
3178 else if (error != 0) {
3183 * a non-zero number of pages present for
3186 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
3187 if ((done_ccb->ccb_h.status &
3188 CAM_DEV_QFRZN) != 0) {
3190 cam_release_devq(done_ccb->ccb_h.path,
3191 /*relsim_flags*/0,
3192 /*reduction*/0,
3193 /*timeout*/0,
3194 /*getcount_only*/0);
3199 free(ataio->data_ptr, M_ATADA);
3201 if ((error == 0)
3202 && (softc->flags & ADA_FLAG_CAN_SUPCAP)) {
3203 softc->state = ADA_STATE_SUP_CAP;
3213 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3217 error = 0;
3220 ataio->data_ptr;
3221 valid_len = ataio->dxfer_len - ataio->resid;
3224 sup_zac_cap) + 1 + sizeof(sup_cap->sup_zac_cap);
3228 zoned = le64dec(sup_cap->zoned_cap);
3237 softc->zone_mode =
3241 softc->zone_mode =
3245 zac_cap = le64dec(sup_cap->sup_zac_cap);
3248 softc->zone_flags |=
3251 softc->zone_flags |=
3254 softc->zone_flags |=
3257 softc->zone_flags |=
3260 softc->zone_flags |=
3265 * ACS-4, r08 on April 28th, 2015.
3271 softc->zone_flags |=
3280 else if (error != 0) {
3286 softc->flags &= ~ADA_FLAG_CAN_SUPCAP;
3290 softc->zone_flags &= ~ADA_ZONE_FLAG_SUP_MASK;
3291 if ((done_ccb->ccb_h.status &
3292 CAM_DEV_QFRZN) != 0) {
3294 cam_release_devq(done_ccb->ccb_h.path,
3295 /*relsim_flags*/0,
3296 /*reduction*/0,
3297 /*timeout*/0,
3298 /*getcount_only*/0);
3303 free(ataio->data_ptr, M_ATADA);
3305 if ((error == 0)
3306 && (softc->flags & ADA_FLAG_CAN_ZONE)) {
3307 softc->state = ADA_STATE_ZONE;
3317 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3322 zi_log = (struct ata_zoned_info_log *)ataio->data_ptr;
3324 valid_len = ataio->dxfer_len - ataio->resid;
3326 version_info) + 1 + sizeof(zi_log->version_info);
3330 tmpvar = le64dec(zi_log->zoned_cap);
3333 softc->zone_flags |=
3336 softc->zone_flags &=
3339 tmpvar = le64dec(zi_log->optimal_seq_zones);
3341 softc->zone_flags |=
3343 softc->optimal_seq_zones = (tmpvar &
3346 softc->zone_flags &=
3348 softc->optimal_seq_zones = 0;
3351 tmpvar =le64dec(zi_log->optimal_nonseq_zones);
3353 softc->zone_flags |=
3355 softc->optimal_nonseq_zones =
3358 softc->zone_flags &=
3360 softc->optimal_nonseq_zones = 0;
3363 tmpvar = le64dec(zi_log->max_seq_req_zones);
3365 softc->zone_flags |=
3367 softc->max_seq_zones =
3370 softc->zone_flags &=
3372 softc->max_seq_zones = 0;
3380 else if (error != 0) {
3381 softc->flags &= ~ADA_FLAG_CAN_ZONE;
3382 softc->flags &= ~ADA_ZONE_FLAG_SET_MASK;
3384 if ((done_ccb->ccb_h.status &
3385 CAM_DEV_QFRZN) != 0) {
3387 cam_release_devq(done_ccb->ccb_h.path,
3388 /*relsim_flags*/0,
3389 /*reduction*/0,
3390 /*timeout*/0,
3391 /*getcount_only*/0);
3395 free(ataio->data_ptr, M_ATADA);
3401 /* No-op. We're polling */
3416 periph = xpt_path_periph(ccb->ccb_h.path);
3417 softc = (struct ada_softc *)periph->softc;
3419 switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
3421 softc->timeouts++;
3429 softc->errors++;
3442 struct disk_params *dp = &softc->params;
3448 dp->secsize = ata_logical_sector_size(&cgd->ident_data);
3449 if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
3450 cgd->ident_data.current_heads != 0 &&
3451 cgd->ident_data.current_sectors != 0) {
3452 dp->heads = cgd->ident_data.current_heads;
3453 dp->secs_per_track = cgd->ident_data.current_sectors;
3454 dp->cylinders = cgd->ident_data.cylinders;
3455 dp->sectors = (uint32_t)cgd->ident_data.current_size_1 |
3456 ((uint32_t)cgd->ident_data.current_size_2 << 16);
3458 dp->heads = cgd->ident_data.heads;
3459 dp->secs_per_track = cgd->ident_data.sectors;
3460 dp->cylinders = cgd->ident_data.cylinders;
3461 dp->sectors = cgd->ident_data.cylinders *
3462 (uint32_t)(dp->heads * dp->secs_per_track);
3464 lbasize = (uint32_t)cgd->ident_data.lba_size_1 |
3465 ((uint32_t)cgd->ident_data.lba_size_2 << 16);
3468 if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
3469 dp->sectors = lbasize;
3472 lbasize48 = ((uint64_t)cgd->ident_data.lba_size48_1) |
3473 ((uint64_t)cgd->ident_data.lba_size48_2 << 16) |
3474 ((uint64_t)cgd->ident_data.lba_size48_3 << 32) |
3475 ((uint64_t)cgd->ident_data.lba_size48_4 << 48);
3476 if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) &&
3478 dp->sectors = lbasize48;
3480 maxio = softc->cpi.maxio; /* Honor max I/O size of SIM */
3481 if (maxio == 0)
3485 if (softc->flags & ADA_FLAG_CAN_48BIT)
3486 maxio = min(maxio, 65536 * softc->params.secsize);
3488 maxio = min(maxio, 256 * softc->params.secsize);
3489 if (softc->quirks & ADA_Q_128KB)
3491 softc->disk->d_maxsize = maxio;
3493 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
3495 if (softc->flags & ADA_FLAG_CAN_TRIM) {
3497 softc->disk->d_delmaxsize = softc->params.secsize *
3498 ATA_DSM_RANGE_MAX * softc->trim_max_ranges;
3499 } else if ((softc->flags & ADA_FLAG_CAN_CFA) &&
3500 !(softc->flags & ADA_FLAG_CAN_48BIT)) {
3502 softc->disk->d_delmaxsize = 256 * softc->params.secsize;
3504 softc->disk->d_delmaxsize = maxio;
3505 if ((softc->cpi.hba_misc & PIM_UNMAPPED) != 0) {
3507 softc->flags |= ADA_FLAG_UNMAPPEDIO;
3509 softc->disk->d_flags = d_flags;
3520 tmpsize = MIN(sizeof(softc->disk->d_descr) - 1,
3521 sizeof(cgd->ident_data.model));
3522 memcpy(softc->disk->d_descr, cgd->ident_data.model, tmpsize);
3523 softc->disk->d_descr[tmpsize] = '\0';
3525 tmpsize = MIN(sizeof(softc->disk->d_ident) - 1,
3526 sizeof(cgd->ident_data.serial));
3527 memcpy(softc->disk->d_ident, cgd->ident_data.serial, tmpsize);
3528 softc->disk->d_ident[tmpsize] = '\0';
3530 softc->disk->d_sectorsize = softc->params.secsize;
3531 softc->disk->d_mediasize = (off_t)softc->params.sectors *
3532 softc->params.secsize;
3533 if (ata_physical_sector_size(&cgd->ident_data) !=
3534 softc->params.secsize) {
3535 softc->disk->d_stripesize =
3536 ata_physical_sector_size(&cgd->ident_data);
3537 softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
3538 ata_logical_sector_offset(&cgd->ident_data)) %
3539 softc->disk->d_stripesize;
3540 } else if (softc->quirks & ADA_Q_4K) {
3541 softc->disk->d_stripesize = 4096;
3542 softc->disk->d_stripeoffset = 0;
3544 softc->disk->d_fwsectors = softc->params.secs_per_track;
3545 softc->disk->d_fwheads = softc->params.heads;
3546 softc->disk->d_rotation_rate = cgd->ident_data.media_rotation_rate;
3547 snprintf(softc->disk->d_attachment, sizeof(softc->disk->d_attachment),
3548 "%s%d", softc->cpi.dev_name, softc->cpi.unit_number);
3557 if (softc->outstanding_cmds > 0) {
3558 if ((softc->flags & ADA_FLAG_WAS_OTAG) == 0)
3559 softc->flags |= ADA_FLAG_NEED_OTAG;
3560 softc->flags &= ~ADA_FLAG_WAS_OTAG;
3565 callout_schedule_sbt(&softc->sendordered_c,
3566 SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
3583 softc = (struct ada_softc *)periph->softc;
3587 (softc->flags & ADA_FLAG_OPEN)) {
3588 adadump(softc->disk, NULL, 0, 0);
3597 if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
3598 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
3604 cam_fill_ataio(&ccb->ataio,
3605 0,
3608 0,
3610 0,
3612 if (softc->flags & ADA_FLAG_CAN_48BIT)
3613 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
3615 ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
3617 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
3619 softc->disk->d_devstat);
3620 if (error != 0)
3621 xpt_print(periph->path, "Synchronize cache failed\n");
3637 /* If we panicked with lock held - not recurse here. */
3641 softc = (struct ada_softc *)periph->softc;
3643 * We only spin-down the drive if it is capable of it..
3645 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
3655 memset(&local_ccb, 0, sizeof(local_ccb));
3656 xpt_setup_ccb(&local_ccb.ccb_h, periph->path,
3660 cam_fill_ataio(&local_ccb, 0, NULL, CAM_DIR_NONE,
3661 0, NULL, 0, ada_default_timeout * 1000);
3663 0, 0, 0);
3667 adaerror, /*cam_flags*/0,
3669 softc->disk->d_devstat);
3670 if (error != 0) {
3671 xpt_print(periph->path,
3677 xpt_print(periph->path,
3678 "disk power mode 0x%02x\n", mode);
3685 xpt_print(periph->path,
3697 xpt_print(periph->path, "spin-down\n");
3699 memset(&local_ccb, 0, sizeof(local_ccb));
3700 xpt_setup_ccb(&local_ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
3704 0,
3707 0,
3709 0,
3711 ata_28bit_cmd(&local_ccb, cmd, 0, 0, 0);
3713 /*cam_flags*/0, /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
3714 softc->disk->d_devstat);
3715 if (error != 0)
3716 xpt_print(periph->path, "Spin-down disk failed\n");
3726 if ((howto & RB_NOSYNC) != 0)
3745 if (ada_spindown_shutdown != 0) {
3748 adaspindown(how, 0);
3761 if (ada_spindown_suspend != 0)
3771 if (ada_spindown_suspend == 0)
3776 softc = (struct ada_softc *)periph->softc;
3778 * We only spin-down the drive if it is capable of it..
3780 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
3786 xpt_print(periph->path, "resume\n");
3792 cam_release_devq(periph->path,
3793 /*relsim_flags*/0,
3794 /*openings*/0,
3795 /*timeout*/0,
3796 /*getcount_only*/0);