From: krw Date: Wed, 2 Mar 2022 17:47:11 +0000 (+0000) Subject: Abstract the memory allocation, scsibus_softc data copying and X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=f84da9bff3c882eb7034ff2560323d6d1c135732;p=openbsd Abstract the memory allocation, scsibus_softc data copying and 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@. --- diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index 6db18c2fd81..c52c5e65ac7 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -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,