Abstract the memory allocation, scsibus_softc data copying and
authorkrw <krw@openbsd.org>
Wed, 2 Mar 2022 17:47:11 +0000 (17:47 +0000)
committerkrw <krw@openbsd.org>
Wed, 2 Mar 2022 17:47:11 +0000 (17:47 +0000)
flag setting bits of creating a scsi_link into scsi_alloc_link().

Shrinks the bloated scsi_probe_link() a bit, makes it possible to
eventually create a useable scsi_link even when scsi_probe_link()
can't attach a device.

Developed from part of a diff submitted by Scott Nicholas via
tech@.

sys/scsi/scsiconf.c

index 6db18c2..c52c5e6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: scsiconf.c,v 1.240 2022/03/02 13:58:08 krw Exp $      */
+/*     $OpenBSD: scsiconf.c,v 1.241 2022/03/02 17:47:11 krw Exp $      */
 /*     $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $       */
 
 /*
@@ -75,6 +75,7 @@ int   scsibussubprint(void *, const char *);
 int    scsibusbioctl(struct device *, u_long, caddr_t);
 #endif /* NBIO > 0 */
 
+struct scsi_link *scsi_alloc_link(struct scsibus_softc *, int, int);
 void   scsi_get_target_luns(struct scsibus_softc *, int,
     struct scsi_lun_array *);
 void   scsi_add_link(struct scsi_link *);
@@ -472,31 +473,15 @@ scsi_probe_lun(struct scsibus_softc *sb, int target, int lun)
        return scsi_probe_link(sb, target, lun, 0);
 }
 
-/*
- * Given a target and lun, ask the device what it is, and find the correct
- * driver table entry.
- *
- * Return 0 if further LUNs are possible, EINVAL if not.
- */
-int
-scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan)
+struct scsi_link *
+scsi_alloc_link(struct scsibus_softc *sb, int target, int lun)
 {
-       struct scsi_attach_args                  sa;
-       const struct scsi_quirk_inquiry_pattern *finger;
-       struct scsi_inquiry_data                *inqbuf, *usbinqbuf;
-       struct scsi_link                        *link, *link0;
-       struct cfdata                           *cf;
-       int                                      inqbytes, priority, rslt = 0;
-       u_int16_t                                devquirks;
-
-       /* Skip this slot if it is already attached and try the next LUN. */
-       if (scsi_get_link(sb, target, lun) != NULL)
-               return 0;
+       struct scsi_link        *link;
 
        link = malloc(sizeof(*link), M_DEVBUF, M_NOWAIT);
        if (link == NULL) {
                SC_DEBUG(link, SDEV_DB2, ("malloc(scsi_link) failed.\n"));
-               return EINVAL;
+               return NULL;
        }
 
        link->state = 0;
@@ -516,28 +501,18 @@ scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan)
        link->pending = 0;
        link->pool = sb->sb_pool;
 
-       SC_DEBUG(link, SDEV_DB2, ("scsi_link created.\n"));
-
-       /* Ask the adapter if this will be a valid device. */
-       if (sb->sb_adapter->dev_probe != NULL &&
-           sb->sb_adapter->dev_probe(link) != 0) {
-               if (lun == 0) {
-                       SC_DEBUG(link, SDEV_DB2, ("dev_probe(link) failed.\n"));
-                       rslt = EINVAL;
-               }
-               goto free;
-       }
+#ifdef SCSIDEBUG
+       if (((sb->sc_dev.dv_unit < 32) &&
+           ((1U << sb->sc_dev.dv_unit) & scsidebug_buses)) &&
+           ((target < 32) && ((1U << target) & scsidebug_targets)) &&
+           ((lun < 32) && ((1U << lun) & scsidebug_luns)))
+               SET(link->flags, scsidebug_level);
+#endif /* SCSIDEBUG */
 
-       /*
-        * If we havent been given an io pool by now then fall back to
-        * using link->openings.
-        */
        if (link->pool == NULL) {
-               link->pool = malloc(sizeof(*link->pool),
-                   M_DEVBUF, M_NOWAIT);
+               link->pool = malloc(sizeof(*link->pool), M_DEVBUF, M_NOWAIT);
                if (link->pool == NULL) {
                        SC_DEBUG(link, SDEV_DB2, ("malloc(pool) failed.\n"));
-                       rslt = ENOMEM;
                        goto bad;
                }
                scsi_iopool_init(link->pool, link,
@@ -546,6 +521,47 @@ scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan)
                SET(link->flags, SDEV_OWN_IOPL);
        }
 
+       SC_DEBUG(link, SDEV_DB2, ("scsi_link created.\n"));
+       return link;
+
+bad:
+       free(link, M_DEVBUF, sizeof(*link));
+       return NULL;
+}
+
+/*
+ * Given a target and lun, ask the device what it is, and find the correct
+ * driver table entry.
+ *
+ * Return 0 if further LUNs are possible, EINVAL if not.
+ */
+int
+scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan)
+{
+       struct scsi_attach_args                  sa;
+       const struct scsi_quirk_inquiry_pattern *finger;
+       struct scsi_inquiry_data                *inqbuf, *usbinqbuf;
+       struct scsi_link                        *link, *link0;
+       struct cfdata                           *cf;
+       int                                      inqbytes, priority, rslt = 0;
+       u_int16_t                                devquirks;
+
+       if (scsi_get_link(sb, target, lun) != NULL)
+               return 0;
+       link = scsi_alloc_link(sb, target, lun);
+       if (link == NULL)
+               return EINVAL;
+
+       /* Ask the adapter if this will be a valid device. */
+       if (sb->sb_adapter->dev_probe != NULL &&
+           sb->sb_adapter->dev_probe(link) != 0) {
+               if (lun == 0) {
+                       SC_DEBUG(link, SDEV_DB2, ("dev_probe(link) failed.\n"));
+                       rslt = EINVAL;
+               }
+               goto free;
+       }
+
        /*
         * Tell drivers that are paying attention to avoid sync/wide/tags until
         * INQUIRY data has been processed and the quirks information is
@@ -554,18 +570,6 @@ scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan)
         */
        devquirks = link->quirks;
        SET(link->quirks, SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS);
-
-       /*
-        * Ask the device what it is.
-        */
-#ifdef SCSIDEBUG
-       if (((sb->sc_dev.dv_unit < 32) &&
-           ((1U << sb->sc_dev.dv_unit) & scsidebug_buses)) &&
-           ((target < 32) && ((1U << target) & scsidebug_targets)) &&
-           ((lun < 32) && ((1U << lun) & scsidebug_luns)))
-               SET(link->flags, scsidebug_level);
-#endif /* SCSIDEBUG */
-
        if (lun == 0) {
                /* Clear any outstanding errors. */
                scsi_test_unit_ready(link, TEST_READY_RETRIES,