1849 if (bufsize != NULL)
1850 *bufsize = 0;
1851
1852 cmd->nc_sqid = 0;
1853 cmd->nc_callback = nvme_wakeup_cmd;
1854 cmd->nc_sqe.sqe_opc = NVME_OPC_GET_FEATURES;
1855 cmd->nc_sqe.sqe_cdw10 = feature;
1856 cmd->nc_sqe.sqe_cdw11 = *res;
1857
1858 /*
1859 * For some of the optional features there doesn't seem to be a method
1860 * of detecting whether it is supported other than using it. This will
1861 * cause "Invalid Field in Command" error, which is normally considered
1862 * a programming error. Set the nc_dontpanic flag to override the panic
1863 * in nvme_check_generic_cmd_status().
1864 */
1865 switch (feature) {
1866 case NVME_FEAT_ARBITRATION:
1867 case NVME_FEAT_POWER_MGMT:
1868 case NVME_FEAT_TEMPERATURE:
1869 case NVME_FEAT_ERROR:
1870 case NVME_FEAT_NQUEUES:
1871 case NVME_FEAT_INTR_COAL:
1872 case NVME_FEAT_INTR_VECT:
1873 case NVME_FEAT_WRITE_ATOM:
1874 case NVME_FEAT_ASYNC_EVENT:
1875 break;
1876
1877 case NVME_FEAT_WRITE_CACHE:
1878 if (!nvme->n_write_cache_present)
1879 goto fail;
1880 break;
1881
1882 case NVME_FEAT_LBA_RANGE:
1883 if (!nvme->n_lba_range_supported)
1884 goto fail;
1885
1886 cmd->nc_dontpanic = B_TRUE;
1887 cmd->nc_sqe.sqe_nsid = nsid;
1888 ASSERT(bufsize != NULL);
1889 *bufsize = NVME_LBA_RANGE_BUFSIZE;
1890 break;
1891
1892 case NVME_FEAT_AUTO_PST:
1893 if (!nvme->n_auto_pst_supported)
1894 goto fail;
1895
1896 ASSERT(bufsize != NULL);
|
1849 if (bufsize != NULL)
1850 *bufsize = 0;
1851
1852 cmd->nc_sqid = 0;
1853 cmd->nc_callback = nvme_wakeup_cmd;
1854 cmd->nc_sqe.sqe_opc = NVME_OPC_GET_FEATURES;
1855 cmd->nc_sqe.sqe_cdw10 = feature;
1856 cmd->nc_sqe.sqe_cdw11 = *res;
1857
1858 /*
1859 * For some of the optional features there doesn't seem to be a method
1860 * of detecting whether it is supported other than using it. This will
1861 * cause "Invalid Field in Command" error, which is normally considered
1862 * a programming error. Set the nc_dontpanic flag to override the panic
1863 * in nvme_check_generic_cmd_status().
1864 */
1865 switch (feature) {
1866 case NVME_FEAT_ARBITRATION:
1867 case NVME_FEAT_POWER_MGMT:
1868 case NVME_FEAT_TEMPERATURE:
1869 case NVME_FEAT_NQUEUES:
1870 case NVME_FEAT_INTR_COAL:
1871 case NVME_FEAT_INTR_VECT:
1872 case NVME_FEAT_WRITE_ATOM:
1873 case NVME_FEAT_ASYNC_EVENT:
1874 break;
1875
1876 case NVME_FEAT_ERROR:
1877 /*
1878 * Some controllers (e.g. INTEL SSDPE2KX010T7) get upset if
1879 * namespace ID of 0 is specified. As we don't currently report
1880 * the "Deallocated or Unwritten Logical Block Error Enable",
1881 * simply set the NS ID to 1.
1882 */
1883 cmd->nc_sqe.sqe_nsid = 1;
1884 break;
1885
1886 case NVME_FEAT_WRITE_CACHE:
1887 if (!nvme->n_write_cache_present)
1888 goto fail;
1889 break;
1890
1891 case NVME_FEAT_LBA_RANGE:
1892 if (!nvme->n_lba_range_supported)
1893 goto fail;
1894
1895 cmd->nc_dontpanic = B_TRUE;
1896 cmd->nc_sqe.sqe_nsid = nsid;
1897 ASSERT(bufsize != NULL);
1898 *bufsize = NVME_LBA_RANGE_BUFSIZE;
1899 break;
1900
1901 case NVME_FEAT_AUTO_PST:
1902 if (!nvme->n_auto_pst_supported)
1903 goto fail;
1904
1905 ASSERT(bufsize != NULL);
|