Print this page
Reduce lint
OS-3878 The pseudo nexus should be FMA capable
OS-3881 pseudonex_detach does not properly check the detach command
Reviewed by: Joshua M. Clulow <josh@sysmgr.org>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
        
*** 81,97 ****
--- 81,101 ----
  static int pseudonex_attach(dev_info_t *, ddi_attach_cmd_t);
  static int pseudonex_detach(dev_info_t *, ddi_detach_cmd_t);
  static int pseudonex_open(dev_t *, int, int, cred_t *);
  static int pseudonex_close(dev_t, int, int, cred_t *);
  static int pseudonex_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
+ static int pseudonex_fm_init(dev_info_t *, dev_info_t *, int,
+     ddi_iblock_cookie_t *);
  static int pseudonex_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
      void *);
  
  static void *pseudonex_state;
  
  typedef struct pseudonex_state {
          dev_info_t *pnx_devi;
+         int pnx_fmcap;
+         ddi_iblock_cookie_t pnx_fm_ibc;
  } pseudonex_state_t;
  
  static struct bus_ops pseudonex_bus_ops = {
          BUSO_REV,
          nullbusmap,             /* bus_map */
*** 114,124 ****
          0,                      /* bus_remove_eventcall */
          0,                      /* bus_post_event */
          NULL,                   /* bus_intr_ctl */
          NULL,                   /* bus_config */
          NULL,                   /* bus_unconfig */
!         NULL,                   /* bus_fm_init */
          NULL,                   /* bus_fm_fini */
          NULL,                   /* bus_fm_access_enter */
          NULL,                   /* bus_fm_access_exit */
          NULL,                   /* bus_power */
          pseudonex_intr_op       /* bus_intr_op */
--- 118,128 ----
          0,                      /* bus_remove_eventcall */
          0,                      /* bus_post_event */
          NULL,                   /* bus_intr_ctl */
          NULL,                   /* bus_config */
          NULL,                   /* bus_unconfig */
!         pseudonex_fm_init,      /* bus_fm_init */
          NULL,                   /* bus_fm_fini */
          NULL,                   /* bus_fm_access_enter */
          NULL,                   /* bus_fm_access_exit */
          NULL,                   /* bus_power */
          pseudonex_intr_op       /* bus_intr_op */
*** 226,235 ****
--- 230,242 ----
          if (ddi_soft_state_zalloc(pseudonex_state, instance) != DDI_SUCCESS)
                  return (DDI_FAILURE);
          pnx_state = ddi_get_soft_state(pseudonex_state, instance);
          pnx_state->pnx_devi = devi;
  
+         pnx_state->pnx_fmcap = DDI_FM_EREPORT_CAPABLE;
+         ddi_fm_init(devi, &pnx_state->pnx_fmcap, &pnx_state->pnx_fm_ibc);
+ 
          if (ddi_create_minor_node(devi, "devctl", S_IFCHR, instance,
              DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
                  ddi_remove_minor_node(devi, NULL);
                  ddi_soft_state_free(pseudonex_state, instance);
                  return (DDI_FAILURE);
*** 245,254 ****
--- 252,265 ----
          int instance = ddi_get_instance(devi);
  
          if (cmd == DDI_SUSPEND)
                  return (DDI_SUCCESS);
  
+         if (cmd != DDI_DETACH)
+                 return (DDI_FAILURE);
+ 
+         ddi_fm_fini(devi);
          ddi_remove_minor_node(devi, NULL);
          ddi_soft_state_free(pseudonex_state, instance);
          return (DDI_SUCCESS);
  }
  
*** 372,381 ****
--- 383,406 ----
          }
          UNLOCK_DEV_OPS(dmp);
          return (-1);
  }
  
+ /* ARGSUSED */
+ static int
+ pseudonex_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
+     ddi_iblock_cookie_t *ibc)
+ {
+         pseudonex_state_t *pnx_state;
+ 
+         pnx_state = ddi_get_soft_state(pseudonex_state, ddi_get_instance(dip));
+         ASSERT(pnx_state != NULL);
+         ASSERT(ibc != NULL);
+         *ibc = pnx_state->pnx_fm_ibc;
+         return (pnx_state->pnx_fmcap & cap);
+ }
+ 
  static int
  pseudonex_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
      void *arg, void *result)
  {
          switch (ctlop) {