summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-11-10 03:51:23 +0000
committersimokawa <simokawa@FreeBSD.org>2003-11-10 03:51:23 +0000
commitd78e17d18b70e0442e87923072c0dee6a55dbaea (patch)
tree43f81ebe56ee7c936dd6d42c65d47f62f8a3b644 /sys/dev/firewire
parent5e2cdf1a7836e71db7db362657e0e3a807199b39 (diff)
downloadFreeBSD-src-d78e17d18b70e0442e87923072c0dee6a55dbaea.zip
FreeBSD-src-d78e17d18b70e0442e87923072c0dee6a55dbaea.tar.gz
* Improve sbp device probe in boot process.
- Notify BUS RESET to CAM in sbp_attach(). - Use last bus reset time to determine login delay. Tested by: imura * Add some sysctl MIB and tunables.
Diffstat (limited to 'sys/dev/firewire')
-rw-r--r--sys/dev/firewire/sbp.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index 67f3a79..6f70ed2 100644
--- a/sys/dev/firewire/sbp.c
+++ b/sys/dev/firewire/sbp.c
@@ -102,8 +102,6 @@
#define SBP_ADDR2LUN(a) (((a) >> 8) & 0xff)
#define SBP_INITIATOR 7
-#define LOGIN_DELAY 1
-
static char *orb_fun_name[] = {
ORB_FUN_NAMES
};
@@ -112,7 +110,9 @@ static int debug = 0;
static int auto_login = 1;
static int max_speed = 2;
static int sbp_cold = 1;
-static int exlogin = 1;
+static int ex_login = 1;
+static int login_delay = 1000; /* msec */
+static int scan_delay = 500; /* msec */
SYSCTL_DECL(_hw_firewire);
SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem");
@@ -123,7 +123,17 @@ SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
"SBP transfer max speed");
SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
- &exlogin, 0, "SBP transfer max speed");
+ &ex_login, 0, "SBP transfer max speed");
+SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
+ &login_delay, 0, "SBP login delay in msec");
+SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
+ &scan_delay, 0, "SBP scan delay in msec");
+
+TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
+TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
+TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
+TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
+TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
#define NEED_RESPONSE 0
@@ -193,7 +203,6 @@ struct sbp_target {
struct sbp_ocb *mgm_ocb_cur;
STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
struct callout mgm_ocb_timeout;
-#define SCAN_DELAY 1
struct callout scan_callout;
STAILQ_HEAD(, fw_xfer) xferlist;
int n_xfer;
@@ -206,7 +215,9 @@ struct sbp_softc {
struct sbp_target targets[SBP_NUM_TARGETS];
struct fw_bind fwb;
bus_dma_tag_t dmat;
+ struct timeval last_busreset;
};
+
static void sbp_post_explore __P((void *));
static void sbp_recv __P((struct fw_xfer *));
static void sbp_mgm_callback __P((struct fw_xfer *));
@@ -229,9 +240,6 @@ static void sbp_free_target __P((struct sbp_target *));
static void sbp_mgm_timeout __P((void *arg));
static void sbp_timeout __P((void *arg));
static void sbp_mgm_orb __P((struct sbp_dev *, int, struct sbp_ocb *));
-#define sbp_login(sdev) \
- callout_reset(&(sdev)->login_callout, LOGIN_DELAY * hz, \
- sbp_login_callout, (void *)(sdev));
MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
@@ -643,6 +651,28 @@ sbp_login_callout(void *arg)
sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
}
+static void
+sbp_login(struct sbp_dev *sdev)
+{
+ struct timeval delta;
+ struct timeval t;
+ int ticks = 0;
+
+ microtime(&delta);
+ timevalsub(&delta, &sdev->target->sbp->last_busreset);
+ t.tv_sec = login_delay / 1000;
+ t.tv_usec = (login_delay % 1000) * 1000;
+ timevalsub(&t, &delta);
+ if (t.tv_sec >= 0 && t.tv_usec > 0)
+ ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
+SBP_DEBUG(0)
+ printf("%s: sec = %ld usec = %ld ticks = %d\n", __FUNCTION__,
+ t.tv_sec, t.tv_usec, ticks);
+END_DEBUG
+ callout_reset(&sdev->login_callout, ticks,
+ sbp_login_callout, (void *)(sdev));
+}
+
#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
&& crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
@@ -734,6 +764,7 @@ sbp_post_busreset(void *arg)
SBP_DEBUG(0)
printf("sbp_post_busreset\n");
END_DEBUG
+ microtime(&sbp->last_busreset);
}
static void
@@ -747,14 +778,16 @@ sbp_post_explore(void *arg)
SBP_DEBUG(0)
printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
END_DEBUG
-#if 0 /*
- * XXX don't let CAM the bus rest. CAM tries to do something with
- * freezed (DEV_RETRY) devices
+ if (sbp_cold > 0)
+ sbp_cold --;
+
+#if 0
+ /*
+ * XXX don't let CAM the bus rest.
+ * CAM tries to do something with freezed (DEV_RETRY) devices.
*/
xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
#endif
- if (sbp_cold > 0)
- sbp_cold --;
/* Gabage Collection */
for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
@@ -980,7 +1013,7 @@ static __inline void
sbp_scan_dev(struct sbp_dev *sdev)
{
sdev->status = SBP_DEV_PROBE;
- callout_reset(&sdev->target->scan_callout, SCAN_DELAY * hz,
+ callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
sbp_cam_scan_target, (void *)sdev->target);
}
@@ -1301,7 +1334,7 @@ END_DEBUG
ocb->orb[2] = htonl(nid << 16);
ocb->orb[3] = htonl(sdev->dma.bus_addr);
ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
- if (exlogin)
+ if (ex_login)
ocb->orb[4] |= htonl(ORB_EXV);
ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD);
@@ -1910,9 +1943,11 @@ END_DEBUG
if (sbp->fd.fc->status != -1) {
s = splfw();
+ sbp_post_busreset((void *)sbp);
sbp_post_explore((void *)sbp);
splx(s);
}
+ xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
return (0);
fail:
OpenPOWER on IntegriCloud