Print this page
9446 some NVMe controllers get upset about NS ID of 0 when checking "Error Recovery" feature


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);