1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2019 Nexenta Systems, Inc.
  14  */
  15 
  16 /*
  17  * Driver attach/detach routines are found here.
  18  */
  19 
  20 /* ---- Private header files ---- */
  21 #include <smartpqi.h>
  22 
  23 void    *pqi_state;
  24 
  25 /* ---- Autoconfigure forward declarations ---- */
  26 static int smartpqi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
  27 static int smartpqi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  28 static int smartpqi_power(dev_info_t *dip, int component, int level);
  29 static int smartpqi_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
  30     void **results);
  31 
  32 /* ---- cb_ops forward declarations ---- */
  33 static int smartpqi_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
  34     cred_t *credp, int *rval);
  35 
  36 static struct cb_ops smartpqi_cb_ops = {
  37         scsi_hba_open,          /* open */
  38         scsi_hba_close,         /* close */
  39         nodev,                  /* strategy */
  40         nodev,                  /* print */
  41         nodev,                  /* dump */
  42         nodev,                  /* read */
  43         nodev,                  /* write */
  44         smartpqi_ioctl,         /* ioctl */
  45         nodev,                  /* devmap */
  46         nodev,                  /* mmap */
  47         nodev,                  /* segmap */
  48         nochpoll,               /* chpoll */
  49         ddi_prop_op,            /* cb_prop_op */
  50         NULL,                   /* streamtab */
  51         D_MP,                   /* cb_flag */
  52         CB_REV,                 /* rev */
  53         nodev,                  /* aread */
  54         nodev                   /* awrite */
  55 };
  56 
  57 static struct dev_ops smartpqi_ops = {
  58         DEVO_REV,               /* dev_rev */
  59         0,                      /* refcnt */
  60         smartpqi_getinfo,       /* info */
  61         nulldev,                /* identify */
  62         nulldev,                /* probe */
  63         smartpqi_attach,        /* attach */
  64         smartpqi_detach,        /* detach */
  65         nodev,                  /* reset */
  66         &smartpqi_cb_ops,   /* driver operations */
  67         NULL,                   /* bus operations */
  68         smartpqi_power,         /* power management */
  69         ddi_quiesce_not_needed, /* quience */
  70 };
  71 
  72 static struct modldrv modldrv = {
  73         &mod_driverops,
  74         SMARTPQI_MOD_STRING,
  75         &smartpqi_ops,
  76 };
  77 
  78 static struct modlinkage modlinkage = {
  79         MODREV_1, &modldrv, NULL
  80 };
  81 
  82 int pqi_do_scan = 0;
  83 int pqi_do_ctrl = 0;
  84 int pqi_offline_target = 0;
  85 int pqi_do_offline = 0;
  86 
  87 /*
  88  * This is used for data I/O DMA memory allocation. (full 64-bit DMA
  89  * physical addresses are supported.)
  90  */
  91 ddi_dma_attr_t smartpqi_dma_attrs = {
  92         DMA_ATTR_V0,            /* attribute layout version             */
  93         0x0ull,                 /* address low - should be 0 (longlong) */
  94         0xffffffffffffffffull, /* address high - 64-bit max     */
  95         0x00666600ull,          /* count max - max DMA object size      */
  96         4096,                   /* allocation alignment requirements    */
  97         0x78,                   /* burstsizes - binary encoded values   */
  98         1,                      /* minxfer - gran. of DMA engine        */
  99         0x00666600ull,          /* maxxfer - gran. of DMA engine        */
 100         0x00666600ull,          /* max segment size (DMA boundary)      */
 101         PQI_MAX_SCATTER_GATHER, /* scatter/gather list length           */
 102         512,                    /* granularity - device transfer size   */
 103         0                       /* flags, set to 0                      */
 104 };
 105 
 106 ddi_device_acc_attr_t smartpqi_dev_attr = {
 107         DDI_DEVICE_ATTR_V1,
 108         DDI_STRUCTURE_LE_ACC,
 109         DDI_STRICTORDER_ACC,
 110         DDI_DEFAULT_ACC
 111 };
 112 
 113 int
 114 _init(void)
 115 {
 116         int     status;
 117 
 118         if ((status = ddi_soft_state_init(&pqi_state,
 119             sizeof (struct pqi_state), SMARTPQI_INITIAL_SOFT_SPACE)) !=
 120             0) {
 121                 return (status);
 122         }
 123 
 124         if ((status = scsi_hba_init(&modlinkage)) != 0) {
 125                 ddi_soft_state_fini(&pqi_state);
 126                 return (status);
 127         }
 128 
 129         if ((status = mod_install(&modlinkage)) != 0) {
 130                 ddi_soft_state_fini(&pqi_state);
 131                 scsi_hba_fini(&modlinkage);
 132         }
 133 
 134         return (status);
 135 }
 136 
 137 int
 138 _fini(void)
 139 {
 140         int     ret;
 141 
 142         if ((ret = mod_remove(&modlinkage)) == 0) {
 143                 scsi_hba_fini(&modlinkage);
 144                 ddi_soft_state_fini(&pqi_state);
 145         }
 146         return (ret);
 147 }
 148 
 149 /*
 150  * The loadable-module _info(9E) entry point
 151  */
 152 int
 153 _info(struct modinfo *modinfop)
 154 {
 155         /* CONSTCOND */
 156         ASSERT(NO_COMPETING_THREADS);
 157 
 158         return (mod_info(&modlinkage, modinfop));
 159 }
 160 
 161 /*ARGSUSED*/
 162 static int smartpqi_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
 163     void **result)
 164 {
 165         int             rc = DDI_FAILURE;
 166         pqi_state_t     s;
 167 
 168         switch (cmd) {
 169         case DDI_INFO_DEVT2DEVINFO:
 170                 if ((s = ddi_get_soft_state(pqi_state, 0)) == NULL)
 171                         break;
 172                 *result = s->s_dip;
 173                 break;
 174 
 175         case DDI_INFO_DEVT2INSTANCE:
 176                 *result = 0;
 177                 rc = DDI_SUCCESS;
 178                 break;
 179 
 180         default:
 181                 break;
 182         }
 183         return (rc);
 184 }
 185 
 186 static int
 187 smartpqi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 188 {
 189         int             instance;
 190         pqi_state_t     s       = NULL;
 191         int             mem_bar = IO_SPACE;
 192         mem_len_pair_t  m;
 193 
 194         switch (cmd) {
 195         case DDI_ATTACH:
 196                 break;
 197 
 198         case DDI_RESUME:
 199         default:
 200                 return (DDI_FAILURE);
 201         }
 202 
 203         instance = ddi_get_instance(dip);
 204 
 205         /* ---- allocate softc structure ---- */
 206         if (ddi_soft_state_zalloc(pqi_state, instance) != DDI_SUCCESS)
 207                 return (DDI_FAILURE);
 208 
 209         if ((s = ddi_get_soft_state(pqi_state, instance)) == NULL)
 210                 goto fail;
 211 
 212         scsi_size_clean(dip);
 213 
 214         s->s_dip = dip;
 215         s->s_instance = instance;
 216         s->s_intr_ready = 0;
 217         s->s_offline = 0;
 218         list_create(&s->s_devnodes, sizeof (struct pqi_device),
 219             offsetof(struct pqi_device, pd_list));
 220         list_create(&s->s_mem_check, sizeof (struct mem_check),
 221             offsetof(struct mem_check, m_node));
 222 
 223         /* ---- Initialize mutex used in interrupt handler ---- */
 224         mutex_init(&s->s_mutex, NULL, MUTEX_DRIVER,
 225             DDI_INTR_PRI(s->s_intr_pri));
 226         mutex_init(&s->s_mem_mutex, NULL, MUTEX_DRIVER, NULL);
 227         mutex_init(&s->s_io_mutex, NULL, MUTEX_DRIVER, NULL);
 228         mutex_init(&s->s_intr_mutex, NULL, MUTEX_DRIVER, NULL);
 229         cv_init(&s->s_quiescedvar, NULL, CV_DRIVER, NULL);
 230         cv_init(&s->s_io_condvar, NULL, CV_DRIVER, NULL);
 231         sema_init(&s->s_sync_rqst, 1, NULL, SEMA_DRIVER, NULL);
 232 
 233         m = pqi_alloc_mem_len(256);
 234         (void) snprintf(m.mem, m.len, "smartpqi_cache%d", instance);
 235         s->s_cmd_cache = kmem_cache_create(m.mem, sizeof (struct pqi_cmd), 0,
 236             pqi_cache_constructor, pqi_cache_destructor, NULL, s, NULL, 0);
 237 
 238         (void) snprintf(m.mem, m.len, "pqi_events_taskq%d", instance);
 239         s->s_events_taskq = ddi_taskq_create(s->s_dip, m.mem, 1,
 240             TASKQ_DEFAULTPRI, 0);
 241         (void) snprintf(m.mem, m.len, "pqi_complete_taskq%d", instance);
 242         s->s_complete_taskq = ddi_taskq_create(s->s_dip, m.mem, 4,
 243             TASKQ_DEFAULTPRI, 0);
 244         pqi_free_mem_len(&m);
 245 
 246         s->s_debug_level = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
 247             DDI_PROP_DONTPASS, "debug", 0);
 248         if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 249             "enable-mpxio", 0) != 0) {
 250                 s->s_enable_mpxio = 1;
 251         }
 252         if (smartpqi_register_intrs(s) == FALSE) {
 253                 dev_err(s->s_dip, CE_WARN, "unable to register interrupts");
 254                 goto fail;
 255         }
 256 
 257         s->s_msg_dma_attr = smartpqi_dma_attrs;
 258         s->s_reg_acc_attr = smartpqi_dev_attr;
 259 
 260         if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&s->s_reg, 0,
 261             /* sizeof (pqi_ctrl_regs_t) */ 0x8000, &s->s_reg_acc_attr,
 262             &s->s_datap) != DDI_SUCCESS) {
 263                 dev_err(s->s_dip, CE_WARN, "map setup failed");
 264                 goto fail;
 265         }
 266 
 267         if (pqi_check_firmware(s) == B_FALSE) {
 268                 dev_err(s->s_dip, CE_WARN, "firmware issue");
 269                 goto fail;
 270         }
 271         if (pqi_prep_full(s) == B_FALSE) {
 272                 goto fail;
 273         }
 274         if (smartpqi_register_hba(s) == FALSE) {
 275                 dev_err(s->s_dip, CE_WARN, "unable to register SCSI interface");
 276                 goto fail;
 277         }
 278         ddi_report_dev(s->s_dip);
 279         s->s_mem_timeo = timeout(pqi_mem_check, s, drv_usectohz(5 * MICROSEC));
 280 
 281         return (DDI_SUCCESS);
 282 
 283 fail:
 284         (void) smartpqi_detach(s->s_dip, 0);
 285         return (DDI_FAILURE);
 286 }
 287 
 288 /*ARGSUSED*/
 289 static int
 290 smartpqi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 291 {
 292         int             instance;
 293         pqi_state_t     s;
 294         pqi_device_t    devp;
 295 
 296         instance = ddi_get_instance(dip);
 297         if ((s = ddi_get_soft_state(pqi_state, instance)) != NULL) {
 298                 if (s->s_rescan != NULL) {
 299                         (void) untimeout(s->s_rescan);
 300                         s->s_rescan = NULL;
 301                 }
 302 
 303                 if (s->s_watchdog != 0) {
 304                         (void) untimeout(s->s_watchdog);
 305                         s->s_watchdog = 0;
 306                 }
 307 
 308                 if (s->s_error_dma != NULL) {
 309                         pqi_free_single(s, s->s_error_dma);
 310                         s->s_error_dma = NULL;
 311                 }
 312                 if (s->s_adminq_dma != NULL) {
 313                         pqi_free_single(s, s->s_adminq_dma);
 314                         s->s_adminq_dma = NULL;
 315                 }
 316                 if (s->s_queue_dma != NULL) {
 317                         pqi_free_single(s, s->s_queue_dma);
 318                         s->s_queue_dma = NULL;
 319                 }
 320 
 321                 /* ---- Safe to always call ---- */
 322                 pqi_free_io_resource(s);
 323 
 324                 if (s->s_cmd_cache != NULL) {
 325                         kmem_cache_destroy(s->s_cmd_cache);
 326                         s->s_cmd_cache = NULL;
 327                 }
 328 
 329                 if (s->s_events_taskq != NULL) {
 330                         ddi_taskq_destroy(s->s_events_taskq);
 331                         s->s_events_taskq = NULL;
 332                 }
 333                 if (s->s_complete_taskq != NULL) {
 334                         ddi_taskq_destroy(s->s_complete_taskq);
 335                         s->s_complete_taskq = NULL;
 336                 }
 337 
 338                 while ((devp = list_head(&s->s_devnodes)) != NULL) {
 339                         /* ---- Better not be any active commands ---- */
 340                         ASSERT(list_is_empty(&devp->pd_cmd_list));
 341 
 342                         ddi_devid_free_guid(devp->pd_guid);
 343                         if (devp->pd_pip != NULL)
 344                                 (void) mdi_pi_free(devp->pd_pip, 0);
 345                         if (devp->pd_pip_offlined)
 346                                 (void) mdi_pi_free(devp->pd_pip_offlined, 0);
 347                         list_destroy(&devp->pd_cmd_list);
 348                         mutex_destroy(&devp->pd_mutex);
 349                         list_remove(&s->s_devnodes, devp);
 350                         PQI_FREE(devp, sizeof (*devp));
 351                 }
 352                 list_destroy(&s->s_devnodes);
 353                 mutex_destroy(&s->s_mutex);
 354                 mutex_destroy(&s->s_io_mutex);
 355                 mutex_destroy(&s->s_intr_mutex);
 356 
 357                 cv_destroy(&s->s_quiescedvar);
 358                 smartpqi_unregister_hba(s);
 359                 smartpqi_unregister_intrs(s);
 360 
 361                 if (s->s_mem_timeo != 0) {
 362                         mutex_enter(&s->s_mem_mutex);
 363                         (void) untimeout(s->s_mem_timeo);
 364                         s->s_mem_timeo = 0;
 365                         mutex_exit(&s->s_mem_mutex);
 366                         mutex_destroy(&s->s_mem_mutex);
 367                 }
 368 
 369                 if (s->s_time_of_day != 0) {
 370                         (void) untimeout(s->s_time_of_day);
 371                         s->s_time_of_day = 0;
 372                 }
 373 
 374                 ddi_soft_state_free(pqi_state, instance);
 375                 ddi_prop_remove_all(dip);
 376         }
 377 
 378         return (DDI_SUCCESS);
 379 }
 380 
 381 /*ARGSUSED*/
 382 static int
 383 smartpqi_power(dev_info_t *dip, int component, int level)
 384 {
 385         return (DDI_SUCCESS);
 386 }
 387 
 388 /*ARGSUSED*/
 389 static int
 390 smartpqi_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
 391     int *rval)
 392 {
 393         return (0);
 394 }