2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/sysctl.h>
39 #include <sys/taskqueue.h>
41 #include <sys/mutex.h>
43 #include <sys/devicestat.h>
44 #include <sys/eventhandler.h>
45 #include <sys/malloc.h>
47 #include <geom/geom_disk.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/cam_periph.h>
58 #include <cam/cam_xpt_periph.h>
59 #include <cam/cam_xpt_internal.h>
60 #include <cam/cam_sim.h>
62 #include <cam/ata/ata_all.h>
69 PMP_STATE_PM_QUIRKS_1,
70 PMP_STATE_PM_QUIRKS_2,
71 PMP_STATE_PM_QUIRKS_3,
82 PMP_FLAG_SCTX_INIT = 0x200
89 /* Offsets into our private area for storing information */
90 #define ccb_state ppriv_field0
91 #define ccb_bp ppriv_ptr1
94 SLIST_ENTRY(pmp_softc) links;
107 #define PMP_EV_RESET 1
108 #define PMP_EV_RESCAN 2
110 struct task sysctl_task;
111 struct sysctl_ctx_list sysctl_ctx;
112 struct sysctl_oid *sysctl_tree;
115 static periph_init_t pmpinit;
116 static void pmpasync(void *callback_arg, u_int32_t code,
117 struct cam_path *path, void *arg);
118 static void pmpsysctlinit(void *context, int pending);
119 static periph_ctor_t pmpregister;
120 static periph_dtor_t pmpcleanup;
121 static periph_start_t pmpstart;
122 static periph_oninv_t pmponinvalidate;
123 static void pmpdone(struct cam_periph *periph,
124 union ccb *done_ccb);
126 #ifndef PMP_DEFAULT_TIMEOUT
127 #define PMP_DEFAULT_TIMEOUT 30 /* Timeout in seconds */
130 #ifndef PMP_DEFAULT_RETRY
131 #define PMP_DEFAULT_RETRY 1
134 #ifndef PMP_DEFAULT_HIDE_SPECIAL
135 #define PMP_DEFAULT_HIDE_SPECIAL 1
138 static int pmp_retry_count = PMP_DEFAULT_RETRY;
139 static int pmp_default_timeout = PMP_DEFAULT_TIMEOUT;
140 static int pmp_hide_special = PMP_DEFAULT_HIDE_SPECIAL;
142 static SYSCTL_NODE(_kern_cam, OID_AUTO, pmp, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
143 "CAM Direct Access Disk driver");
144 SYSCTL_INT(_kern_cam_pmp, OID_AUTO, retry_count, CTLFLAG_RWTUN,
145 &pmp_retry_count, 0, "Normal I/O retry count");
146 SYSCTL_INT(_kern_cam_pmp, OID_AUTO, default_timeout, CTLFLAG_RWTUN,
147 &pmp_default_timeout, 0, "Normal I/O timeout (in seconds)");
148 SYSCTL_INT(_kern_cam_pmp, OID_AUTO, hide_special, CTLFLAG_RWTUN,
149 &pmp_hide_special, 0, "Hide extra ports");
151 static struct periph_driver pmpdriver =
154 TAILQ_HEAD_INITIALIZER(pmpdriver.units), /* generation */ 0,
158 PERIPHDRIVER_DECLARE(pmp, pmpdriver);
166 * Install a global async callback. This callback will
167 * receive async callbacks like "new device found".
169 status = xpt_register_async(AC_FOUND_DEVICE, pmpasync, NULL, NULL);
171 if (status != CAM_REQ_CMP) {
172 printf("pmp: Failed to attach master async callback "
173 "due to status 0x%x!\n", status);
178 pmpfreeze(struct cam_periph *periph, int mask)
180 struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
181 struct cam_path *dpath;
184 mask &= ~softc->frozen;
185 for (i = 0; i < 15; i++) {
186 if ((mask & (1 << i)) == 0)
188 if (xpt_create_path(&dpath, periph,
189 xpt_path_path_id(periph->path),
190 i, 0) == CAM_REQ_CMP) {
191 softc->frozen |= (1 << i);
192 xpt_acquire_device(dpath->device);
193 cam_freeze_devq(dpath);
194 xpt_free_path(dpath);
200 pmprelease(struct cam_periph *periph, int mask)
202 struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
203 struct cam_path *dpath;
206 mask &= softc->frozen;
207 for (i = 0; i < 15; i++) {
208 if ((mask & (1 << i)) == 0)
210 if (xpt_create_path(&dpath, periph,
211 xpt_path_path_id(periph->path),
212 i, 0) == CAM_REQ_CMP) {
213 softc->frozen &= ~(1 << i);
214 cam_release_devq(dpath, 0, 0, 0, FALSE);
215 xpt_release_device(dpath->device);
216 xpt_free_path(dpath);
222 pmponinvalidate(struct cam_periph *periph)
224 struct cam_path *dpath;
228 * De-register any async callbacks.
230 xpt_register_async(0, pmpasync, periph, periph->path);
232 for (i = 0; i < 15; i++) {
233 if (xpt_create_path(&dpath, periph,
234 xpt_path_path_id(periph->path),
235 i, 0) == CAM_REQ_CMP) {
236 xpt_async(AC_LOST_DEVICE, dpath, NULL);
237 xpt_free_path(dpath);
240 pmprelease(periph, -1);
244 pmpcleanup(struct cam_periph *periph)
246 struct pmp_softc *softc;
248 softc = (struct pmp_softc *)periph->softc;
250 cam_periph_unlock(periph);
253 * If we can't free the sysctl tree, oh well...
255 if ((softc->flags & PMP_FLAG_SCTX_INIT) != 0
256 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
257 xpt_print(periph->path, "can't remove sysctl context\n");
260 free(softc, M_DEVBUF);
261 cam_periph_lock(periph);
265 pmpasync(void *callback_arg, u_int32_t code,
266 struct cam_path *path, void *arg)
268 struct cam_periph *periph;
269 struct pmp_softc *softc;
271 periph = (struct cam_periph *)callback_arg;
273 case AC_FOUND_DEVICE:
275 struct ccb_getdev *cgd;
278 cgd = (struct ccb_getdev *)arg;
282 if (cgd->protocol != PROTO_SATAPM)
286 * Allocate a peripheral instance for
287 * this device and start the probe
290 status = cam_periph_alloc(pmpregister, pmponinvalidate,
291 pmpcleanup, pmpstart,
292 "pmp", CAM_PERIPH_BIO,
294 AC_FOUND_DEVICE, cgd);
296 if (status != CAM_REQ_CMP
297 && status != CAM_REQ_INPROG)
298 printf("pmpasync: Unable to attach to new device "
299 "due to status 0x%x\n", status);
305 softc = (struct pmp_softc *)periph->softc;
306 cam_periph_async(periph, code, path, arg);
307 if (code == AC_SCSI_AEN)
308 softc->events |= PMP_EV_RESCAN;
310 softc->events |= PMP_EV_RESET;
311 if (code == AC_SCSI_AEN && softc->state != PMP_STATE_NORMAL)
314 pmpfreeze(periph, softc->found);
315 if (code == AC_SENT_BDR || code == AC_BUS_RESET)
316 softc->found = 0; /* We have to reset everything. */
317 if (softc->state == PMP_STATE_NORMAL) {
318 if (cam_periph_acquire(periph) == 0) {
319 if (softc->pm_pid == 0x37261095 ||
320 softc->pm_pid == 0x38261095)
321 softc->state = PMP_STATE_PM_QUIRKS_1;
323 softc->state = PMP_STATE_PRECONFIG;
324 xpt_schedule(periph, CAM_PRIORITY_DEV);
326 pmprelease(periph, softc->found);
333 cam_periph_async(periph, code, path, arg);
339 pmpsysctlinit(void *context, int pending)
341 struct cam_periph *periph;
342 struct pmp_softc *softc;
343 char tmpstr[32], tmpstr2[16];
345 periph = (struct cam_periph *)context;
346 if (cam_periph_acquire(periph) != 0)
349 softc = (struct pmp_softc *)periph->softc;
350 snprintf(tmpstr, sizeof(tmpstr), "CAM PMP unit %d", periph->unit_number);
351 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
353 sysctl_ctx_init(&softc->sysctl_ctx);
354 softc->flags |= PMP_FLAG_SCTX_INIT;
355 softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
356 SYSCTL_STATIC_CHILDREN(_kern_cam_pmp), OID_AUTO, tmpstr2,
357 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, "device_index");
358 if (softc->sysctl_tree == NULL) {
359 printf("pmpsysctlinit: unable to allocate sysctl tree\n");
360 cam_periph_release(periph);
364 cam_periph_release(periph);
368 pmpregister(struct cam_periph *periph, void *arg)
370 struct pmp_softc *softc;
371 struct ccb_getdev *cgd;
373 cgd = (struct ccb_getdev *)arg;
375 printf("pmpregister: no getdev CCB, can't register device\n");
376 return(CAM_REQ_CMP_ERR);
379 softc = (struct pmp_softc *)malloc(sizeof(*softc), M_DEVBUF,
383 printf("pmpregister: Unable to probe new device. "
384 "Unable to allocate softc\n");
385 return(CAM_REQ_CMP_ERR);
387 periph->softc = softc;
389 softc->pm_pid = ((uint32_t *)&cgd->ident_data)[0];
390 softc->pm_prv = ((uint32_t *)&cgd->ident_data)[1];
391 TASK_INIT(&softc->sysctl_task, 0, pmpsysctlinit, periph);
393 xpt_announce_periph(periph, NULL);
396 * Add async callbacks for bus reset and
397 * bus device reset calls. I don't bother
398 * checking if this fails as, in most cases,
399 * the system will function just fine without
400 * them and the only alternative would be to
401 * not attach the device on failure.
403 xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
404 AC_SCSI_AEN, pmpasync, periph, periph->path);
407 * Take an exclusive refcount on the periph while pmpstart is called
408 * to finish the probe. The reference will be dropped in pmpdone at
411 (void)cam_periph_acquire(periph);
413 softc->state = PMP_STATE_PORTS;
414 softc->events = PMP_EV_RESCAN;
415 xpt_schedule(periph, CAM_PRIORITY_DEV);
421 pmpstart(struct cam_periph *periph, union ccb *start_ccb)
423 struct ccb_trans_settings cts;
424 struct ccb_ataio *ataio;
425 struct pmp_softc *softc;
426 struct cam_path *dpath;
429 softc = (struct pmp_softc *)periph->softc;
430 ataio = &start_ccb->ataio;
432 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("pmpstart\n"));
434 if (softc->restart) {
436 if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095)
437 softc->state = min(softc->state, PMP_STATE_PM_QUIRKS_1);
439 softc->state = min(softc->state, PMP_STATE_PRECONFIG);
441 /* Fetch user wanted device speed. */
442 if (softc->state == PMP_STATE_RESET ||
443 softc->state == PMP_STATE_CONNECT) {
444 if (xpt_create_path(&dpath, periph,
445 xpt_path_path_id(periph->path),
446 softc->pm_step, 0) == CAM_REQ_CMP) {
447 bzero(&cts, sizeof(cts));
448 xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NONE);
449 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
450 cts.type = CTS_TYPE_USER_SETTINGS;
451 xpt_action((union ccb *)&cts);
452 if (cts.xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
453 revision = cts.xport_specific.sata.revision;
454 xpt_free_path(dpath);
457 switch (softc->state) {
458 case PMP_STATE_PORTS:
459 cam_fill_ataio(ataio,
462 /*flags*/CAM_DIR_NONE,
466 pmp_default_timeout * 1000);
467 ata_pm_read_cmd(ataio, 2, 15);
470 case PMP_STATE_PM_QUIRKS_1:
471 case PMP_STATE_PM_QUIRKS_3:
472 cam_fill_ataio(ataio,
475 /*flags*/CAM_DIR_NONE,
479 pmp_default_timeout * 1000);
480 ata_pm_read_cmd(ataio, 129, 15);
483 case PMP_STATE_PM_QUIRKS_2:
484 cam_fill_ataio(ataio,
487 /*flags*/CAM_DIR_NONE,
491 pmp_default_timeout * 1000);
492 ata_pm_write_cmd(ataio, 129, 15, softc->caps & ~0x1);
495 case PMP_STATE_PRECONFIG:
496 /* Get/update host SATA capabilities. */
497 bzero(&cts, sizeof(cts));
498 xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
499 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
500 cts.type = CTS_TYPE_CURRENT_SETTINGS;
501 xpt_action((union ccb *)&cts);
502 if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
503 softc->caps = cts.xport_specific.sata.caps;
506 cam_fill_ataio(ataio,
509 /*flags*/CAM_DIR_NONE,
513 pmp_default_timeout * 1000);
514 ata_pm_write_cmd(ataio, 0x60, 15, 0x0);
516 case PMP_STATE_RESET:
517 cam_fill_ataio(ataio,
520 /*flags*/CAM_DIR_NONE,
524 pmp_default_timeout * 1000);
525 ata_pm_write_cmd(ataio, 2, softc->pm_step,
527 ((softc->found & (1 << softc->pm_step)) ? 0 : 1));
529 case PMP_STATE_CONNECT:
530 cam_fill_ataio(ataio,
533 /*flags*/CAM_DIR_NONE,
537 pmp_default_timeout * 1000);
538 ata_pm_write_cmd(ataio, 2, softc->pm_step,
541 case PMP_STATE_CHECK:
542 cam_fill_ataio(ataio,
545 /*flags*/CAM_DIR_NONE,
549 pmp_default_timeout * 1000);
550 ata_pm_read_cmd(ataio, 0, softc->pm_step);
552 case PMP_STATE_CLEAR:
554 cam_fill_ataio(ataio,
557 /*flags*/CAM_DIR_NONE,
561 pmp_default_timeout * 1000);
562 ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
564 case PMP_STATE_CONFIG:
565 cam_fill_ataio(ataio,
568 /*flags*/CAM_DIR_NONE,
572 pmp_default_timeout * 1000);
573 ata_pm_write_cmd(ataio, 0x60, 15, 0x07 |
574 ((softc->caps & CTS_SATA_CAPS_H_AN) ? 0x08 : 0));
579 xpt_action(start_ccb);
583 pmpdone(struct cam_periph *periph, union ccb *done_ccb)
585 struct ccb_trans_settings cts;
586 struct pmp_softc *softc;
587 struct ccb_ataio *ataio;
588 struct cam_path *dpath;
589 u_int32_t priority, res;
592 softc = (struct pmp_softc *)periph->softc;
593 ataio = &done_ccb->ataio;
595 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("pmpdone\n"));
597 priority = done_ccb->ccb_h.pinfo.priority;
599 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
600 if (cam_periph_error(done_ccb, 0, 0) == ERESTART) {
602 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
603 cam_release_devq(done_ccb->ccb_h.path,
612 if (softc->restart) {
614 xpt_release_ccb(done_ccb);
615 if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095)
616 softc->state = min(softc->state, PMP_STATE_PM_QUIRKS_1);
618 softc->state = min(softc->state, PMP_STATE_PRECONFIG);
619 xpt_schedule(periph, priority);
623 switch (softc->state) {
624 case PMP_STATE_PORTS:
625 softc->pm_ports = (ataio->res.lba_high << 24) +
626 (ataio->res.lba_mid << 16) +
627 (ataio->res.lba_low << 8) +
628 ataio->res.sector_count;
629 if (pmp_hide_special) {
631 * This PMP declares 6 ports, while only 5 of them
632 * are real. Port 5 is a SEMB port, probing which
633 * causes timeouts if external SEP is not connected
636 if ((softc->pm_pid == 0x37261095 ||
637 softc->pm_pid == 0x38261095) &&
638 softc->pm_ports == 6)
642 * This PMP declares 7 ports, while only 5 of them
643 * are real. Port 5 is a fake "Config Disk" with
644 * 640 sectors size. Port 6 is a SEMB port.
646 if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
650 * These PMPs have extra configuration port.
652 if (softc->pm_pid == 0x57231095 ||
653 softc->pm_pid == 0x57331095 ||
654 softc->pm_pid == 0x57341095 ||
655 softc->pm_pid == 0x57441095)
658 printf("%s%d: %d fan-out ports\n",
659 periph->periph_name, periph->unit_number,
661 if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095)
662 softc->state = PMP_STATE_PM_QUIRKS_1;
664 softc->state = PMP_STATE_PRECONFIG;
665 xpt_release_ccb(done_ccb);
666 xpt_schedule(periph, priority);
669 case PMP_STATE_PM_QUIRKS_1:
670 softc->caps = (ataio->res.lba_high << 24) +
671 (ataio->res.lba_mid << 16) +
672 (ataio->res.lba_low << 8) +
673 ataio->res.sector_count;
674 if (softc->caps & 0x1)
675 softc->state = PMP_STATE_PM_QUIRKS_2;
677 softc->state = PMP_STATE_PRECONFIG;
678 xpt_release_ccb(done_ccb);
679 xpt_schedule(periph, priority);
682 case PMP_STATE_PM_QUIRKS_2:
684 softc->state = PMP_STATE_PM_QUIRKS_3;
686 softc->state = PMP_STATE_PRECONFIG;
687 xpt_release_ccb(done_ccb);
688 xpt_schedule(periph, priority);
691 case PMP_STATE_PM_QUIRKS_3:
692 res = (ataio->res.lba_high << 24) +
693 (ataio->res.lba_mid << 16) +
694 (ataio->res.lba_low << 8) +
695 ataio->res.sector_count;
696 printf("%s%d: Disabling SiI3x26 R_OK in GSCR_POLL: %x->%x\n",
697 periph->periph_name, periph->unit_number, softc->caps, res);
698 softc->state = PMP_STATE_PRECONFIG;
699 xpt_release_ccb(done_ccb);
700 xpt_schedule(periph, priority);
703 case PMP_STATE_PRECONFIG:
705 softc->state = PMP_STATE_RESET;
706 softc->reset |= ~softc->found;
707 xpt_release_ccb(done_ccb);
708 xpt_schedule(periph, priority);
710 case PMP_STATE_RESET:
712 if (softc->pm_step >= softc->pm_ports) {
714 cam_freeze_devq(periph->path);
715 cam_release_devq(periph->path,
716 RELSIM_RELEASE_AFTER_TIMEOUT,
720 softc->state = PMP_STATE_CONNECT;
722 xpt_release_ccb(done_ccb);
723 xpt_schedule(periph, priority);
725 case PMP_STATE_CONNECT:
727 if (softc->pm_step >= softc->pm_ports) {
730 cam_freeze_devq(periph->path);
731 cam_release_devq(periph->path,
732 RELSIM_RELEASE_AFTER_TIMEOUT,
736 softc->state = PMP_STATE_CHECK;
738 xpt_release_ccb(done_ccb);
739 xpt_schedule(periph, priority);
741 case PMP_STATE_CHECK:
742 res = (ataio->res.lba_high << 24) +
743 (ataio->res.lba_mid << 16) +
744 (ataio->res.lba_low << 8) +
745 ataio->res.sector_count;
746 if (((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) ||
747 (res & 0x600) != 0) {
749 printf("%s%d: port %d status: %08x\n",
750 periph->periph_name, periph->unit_number,
751 softc->pm_step, res);
753 /* Report device speed if it is online. */
754 if ((res & 0xf0f) == 0x103 &&
755 xpt_create_path(&dpath, periph,
756 xpt_path_path_id(periph->path),
757 softc->pm_step, 0) == CAM_REQ_CMP) {
758 bzero(&cts, sizeof(cts));
759 xpt_setup_ccb(&cts.ccb_h, dpath, CAM_PRIORITY_NONE);
760 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
761 cts.type = CTS_TYPE_CURRENT_SETTINGS;
762 cts.xport_specific.sata.revision = (res & 0x0f0) >> 4;
763 cts.xport_specific.sata.valid = CTS_SATA_VALID_REVISION;
764 cts.xport_specific.sata.caps = softc->caps &
765 (CTS_SATA_CAPS_H_PMREQ |
766 CTS_SATA_CAPS_H_DMAAA |
768 cts.xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
769 xpt_action((union ccb *)&cts);
770 xpt_free_path(dpath);
772 softc->found |= (1 << softc->pm_step);
775 if (softc->pm_try < 10) {
776 cam_freeze_devq(periph->path);
777 cam_release_devq(periph->path,
778 RELSIM_RELEASE_AFTER_TIMEOUT,
785 printf("%s%d: port %d status: %08x\n",
786 periph->periph_name, periph->unit_number,
787 softc->pm_step, res);
789 softc->found &= ~(1 << softc->pm_step);
790 if (xpt_create_path(&dpath, periph,
791 done_ccb->ccb_h.path_id,
792 softc->pm_step, 0) == CAM_REQ_CMP) {
793 xpt_async(AC_LOST_DEVICE, dpath, NULL);
794 xpt_free_path(dpath);
799 if (softc->pm_step >= softc->pm_ports) {
800 if (softc->reset & softc->found) {
801 cam_freeze_devq(periph->path);
802 cam_release_devq(periph->path,
803 RELSIM_RELEASE_AFTER_TIMEOUT,
808 softc->state = PMP_STATE_CLEAR;
811 xpt_release_ccb(done_ccb);
812 xpt_schedule(periph, priority);
814 case PMP_STATE_CLEAR:
816 if (softc->pm_step >= softc->pm_ports) {
817 softc->state = PMP_STATE_CONFIG;
820 xpt_release_ccb(done_ccb);
821 xpt_schedule(periph, priority);
823 case PMP_STATE_CONFIG:
824 for (i = 0; i < softc->pm_ports; i++) {
827 if ((softc->found & (1 << i)) == 0)
829 if (xpt_create_path(&dpath, periph,
830 xpt_path_path_id(periph->path),
831 i, 0) != CAM_REQ_CMP) {
832 printf("pmpdone: xpt_create_path failed\n");
835 /* If we did hard reset to this device, inform XPT. */
836 if ((softc->reset & softc->found & (1 << i)) != 0)
837 xpt_async(AC_SENT_BDR, dpath, NULL);
838 /* If rescan requested, scan this device. */
839 if (softc->events & PMP_EV_RESCAN) {
840 ccb = xpt_alloc_ccb_nowait();
842 xpt_free_path(dpath);
845 xpt_setup_ccb(&ccb->ccb_h, dpath, CAM_PRIORITY_XPT);
848 xpt_free_path(dpath);
855 xpt_release_ccb(done_ccb);
856 softc->state = PMP_STATE_NORMAL;
859 pmprelease(periph, -1);
860 cam_periph_release_locked(periph);