-/* $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 $ */
/*
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 *);
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;
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,
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
*/
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,