Date: Thu, 22 May 2008 10:23:53 -0700 From: Sean Bruno <sbruno@miralink.com> To: freebsd-firewire@FreeBSD.org Cc: simokawa@ieee.org Subject: Current sbp_targ diff Message-ID: <4835AC29.4030802@miralink.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
I've been quiet lately but I had some time at BSDCAN to cleanup some of
my firewire sbp_targ diffs and would like to get them out for review.
1. I've added a new XPORT_FW type to sys/cam/cam_ccb.h for firewire. I
have added a couple of patches from RELENG_7 to my tree, but they can be
ignored:
Index: cam/cam_ccb.h
===================================================================
--- cam/cam_ccb.h (.../FreeBSD_RELENG_6_13APR07/src/sys)
(revision 5436)
+++ cam/cam_ccb.h (.../miralink.FreeBSD.6/src/sys)
(revision 5436)
@@ -226,14 +223,15 @@
XPORT_SSA, /* Serial Storage Architecture */
XPORT_USB, /* Universal Serial Bus */
XPORT_PPB, /* Parallel Port Bus */
- XPORT_ATA /* AT Attachment */
+ XPORT_ATA, /* AT Attachment */
+ XPORT_SAS, /* Serial Attached SCSI */
+ XPORT_FW /* FireWire 1394a/b */
} cam_xport;
2. I've added a new file to sbp_targ(fwcsr.c) that currently only
handles the Busy Timeout register, but will undoubtably handle more in
the future:
Index: modules/firewire/firewire/Makefile
===================================================================
--- modules/firewire/firewire/Makefile
(.../FreeBSD_RELENG_6_13APR07/src/sys) (revision 5436)
+++ modules/firewire/firewire/Makefile
(.../miralink.FreeBSD.6/src/sys) (revision 5436)
@@ -9,7 +9,8 @@
firewire.c firewire.h firewire_phy.h firewirereg.h \
fwohci.c fwohci_pci.c fwohcireg.h fwohcivar.h \
iec13213.h iec68113.h \
- fwcrom.c fwdev.c fwmem.c fwmem.h fwdma.c fwdma.h
+ fwcrom.c fwdev.c fwmem.c fwmem.h fwdma.c fwdma.h \
+ fwcsr.c fwcsr.h
.include <bsd.kmod.mk>
Index: conf/files
===================================================================
--- conf/files (.../FreeBSD_RELENG_6_13APR07/src/sys) (revision 5436)
+++ conf/files (.../miralink.FreeBSD.6/src/sys) (revision 5436)
@@ -617,6 +617,7 @@
dev/fe/if_fe_pccard.c optional fe pccard
dev/firewire/firewire.c optional firewire
dev/firewire/fwcrom.c optional firewire
+dev/firewire/fwcsr.c optional firewire
dev/firewire/fwdev.c optional firewire
dev/firewire/fwdma.c optional firewire
dev/firewire/fwmem.c optional firewire
3. Finally, the code. I'm attaching a diff, however it's pretty
intrusive so I'm also placing a tar ball of the code on my web server at:
http://www.consultcsg.com/firewire_sbp-targ.tgz so you can review the
entirety of the code at your leisure.
I am still working on the code at this time and will be generating even
more intrusive patches to support SBP-2 and possibly SBP-3 soon-ish.
--
Sean Bruno
MiraLink Corporation
6015 NE 80th Ave, Ste 100
Portland, OR 97218
Phone 503-621-5143
Fax 503-621-5199
[-- Attachment #2 --]
Index: fwcsr.c
===================================================================
--- fwcsr.c (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ fwcsr.c (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -1,85 +0,0 @@
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/iec13213.h>
-#include <dev/firewire/sbp.h>
-#include <dev/firewire/fwmem.h>
-#include <dev/firewire/fwcsr.h>
-
-void
-fwcsr_busy_timeout_init(struct fw_bind *busy_timeout,
- struct firewire_dev_comm *fd,
- void *dev_softc,
- struct malloc_type *dev_type,
- uint32_t send_len,
- uint32_t recv_len,
- uint32_t max_lun)
-{
- busy_timeout->start = 0xfffff0000000 | BUSY_TIMEOUT;
- busy_timeout->end = 0xfffff0000000 | BUSY_TIMEOUT;
-
- STAILQ_INIT(&busy_timeout->xferlist);
- fw_xferlist_add(&busy_timeout->xferlist, dev_type,
- /*send*/ send_len, /*recv*/ recv_len,
- max_lun,
- fd->fc, dev_softc, fwcsr_busy_timeout_handler);
- fw_bindadd(fd->fc, busy_timeout);
-}
-
-void
-fwcsr_busy_timeout_stop(struct fw_bind *busy_timeout,
- struct firewire_dev_comm *fd)
-{
- fw_xferlist_remove(&busy_timeout->xferlist);
- fw_bindremove(fd->fc, busy_timeout);
-}
-
-void
-fwcsr_busy_timeout_handler(struct fw_xfer *xfer)
-{
- struct fw_pkt *fp, *sfp;
- struct fw_device *fwdev;
- uint32_t lo = 0;
- int s, rtcode;
- struct firewire_softc *sc;
-
- s = splfw();
- sc = (struct firewire_softc *)xfer->sc;
- fp = &xfer->recv.hdr;
- fwdev = fw_noderesolve_nodeid(sc->fc, fp->mode.wreqb.src & 0x3f);
- if (fwdev == NULL) {
- printf("%s: cannot resolve nodeid=%d\n",
- __func__, fp->mode.wreqb.src & 0x3f);
- rtcode = RESP_TYPE_ERROR; /* XXX */
- } else {
- printf("%s: BUSY_TIMEOUT Recieved\n", __func__);
- rtcode = 0;
- }
- if (rtcode != 0)
- printf("%s: rtcode = %d lo == 0x%x\n", __func__, rtcode, lo);
-
- sfp = &xfer->send.hdr;
- xfer->send.spd = FWSPD_S400;
-#if 0
- xfer->hand = fw_busy_timeout_resp_callback;
-#endif
- sfp->mode.wres.dst = fp->mode.wreqb.src;
- sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt;
- sfp->mode.wres.tcode = FWTCODE_WRES;
- sfp->mode.wres.rtcode = rtcode;
- sfp->mode.wres.pri = 0;
-
- fw_asyreq(xfer->fc, -1, xfer);
- splx(s);
-}
-
Index: fwcsr.h
===================================================================
--- fwcsr.h (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ fwcsr.h (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -1,5 +0,0 @@
-void fwcsr_busy_timeout_handler(struct fw_xfer *);
-void fwcsr_busy_timeout_init(struct fw_bind *, struct firewire_dev_comm *,
- void *, struct malloc_type *, uint32_t,
- uint32_t, uint32_t);
-void fwcsr_busy_timeout_stop(struct fw_bind *, struct firewire_dev_comm *);
Index: sbp_targ.c
===================================================================
--- sbp_targ.c (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ sbp_targ.c (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -53,7 +53,6 @@
#include <dev/firewire/iec13213.h>
#include <dev/firewire/sbp.h>
#include <dev/firewire/fwmem.h>
-#include <dev/firewire/fwcsr.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -62,7 +61,6 @@
#include <cam/cam_debug.h>
#include <cam/cam_periph.h>
#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_message.h>
#define SBP_TARG_RECV_LEN 8
#define MAX_INITIATORS 8
@@ -75,10 +73,9 @@
* BASE 0xffff f001 0000 management port
* BASE 0xffff f001 0020 command port for login id 0
* BASE 0xffff f001 0040 command port for login id 1
- * BASE 0xffff f001 (0x20 * [login_id + 1]) for login_id
*
*/
-#define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 0000 */
+#define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 000 */
#define SBP_TARG_BIND_HI 0xffff
#define SBP_TARG_BIND_LO(l) (0xf0000000 + SBP_TARG_MGM + 0x20 * ((l) + 1))
#define SBP_TARG_BIND_START (((u_int64_t)SBP_TARG_BIND_HI << 32) | \
@@ -91,16 +88,12 @@
#define FETCH_CMD 1
#define FETCH_POINTER 2
-#define F_LINK_ACTIVE (1 << 0) /* The F/W link is active */
-#define F_ATIO_STARVED (1 << 1) /* We are out of ATIO's */
-#define F_LOGIN (1 << 2) /* This initiator has logged in */
-#define F_HOLD (1 << 3) /* Hold on to this login */
-#define F_FREEZED (1 << 4) /* Frozen login, usually a bus reset occured */
-#define F_RECYCLE_LOGIN (1 << 5) /* This login is to be reused due */
- /* to login before SBP_TARG_HOLD_TIMEOUT */
+#define F_LINK_ACTIVE (1 << 0)
+#define F_ATIO_STARVED (1 << 1)
+#define F_LOGIN (1 << 2)
+#define F_HOLD (1 << 3)
+#define F_FREEZED (1 << 4)
-#define SBP_TARG_HOLD_TIMEOUT 1
-
MALLOC_DEFINE(M_SBP_TARG, "sbp_targ", "SBP-II/FireWire target mode");
static int debug = 0;
@@ -141,7 +134,6 @@
struct cam_sim *sim;
struct cam_path *path;
struct fw_bind fwb;
- struct fw_bind busy_timeout;
int ndevs;
int flags;
struct crom_chunk unit;
@@ -176,10 +168,6 @@
struct morb4 {
#if BYTE_ORDER == BIG_ENDIAN
- uint16_t reserved;
- uint16_t off_hi;
- uint32_t off_lo;
- uint64_t reserved2;
uint32_t n:1,
rq_fmt:2,
:9,
@@ -191,26 +179,9 @@
:9,
rq_fmt:2,
n:1;
- uint64_t reserved2;
- uint32_t off_lo;
- uint16_t off_hi;
- uint16_t reserved;
#endif
};
-/*
- * Urestricted page table format
- * states that the segment length
- * and high base addr are in the first
- * 32 bits and the base low is in
- * the second
- */
-struct unrestricted_page_table_fmt {
- uint16_t segment_len;
- uint16_t segment_base_high;
- uint32_t segment_base_low;
-};
-
struct orb_info {
struct sbp_targ_softc *sc;
struct fw_device *fwdev;
@@ -233,24 +204,10 @@
struct corb4 orb4;
STAILQ_ENTRY(orb_info) link;
uint32_t orb[8];
- struct unrestricted_page_table_fmt *page_table;
- struct unrestricted_page_table_fmt *cur_pte;
- struct unrestricted_page_table_fmt *last_pte;
- uint32_t last_block_read;
+ uint32_t *page_table;
struct sbp_status status;
};
-struct agent_state {
- uint32_t fetch_agent_state;
-#define AGENT_STATE_RESET 0
-#define AGENT_STATE_ACTIVE 1
-#define AGENT_STATE_SUSPENDED 2
-#define AGENT_STATE_DEAD 3
- uint32_t bus_reset_command_reset_init_vals;
- uint32_t read_vals;
- uint32_t write_effects;
-};
-
static char *orb_fun_name[] = {
ORB_FUN_NAMES
};
@@ -258,8 +215,6 @@
static void sbp_targ_recv(struct fw_xfer *);
static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *,
uint16_t, uint32_t, struct sbp_targ_login *, int);
-static void sbp_targ_xfer_pt(struct orb_info *);
-static void sbp_targ_send_agent_state(struct fw_xfer *);
static void
sbp_targ_identify(driver_t *driver, device_t parent)
@@ -287,22 +242,18 @@
struct orb_info *orbi, *next;
if (login == NULL) {
+ printf("%s: login = NULL\n", __func__);
return;
}
for (orbi = STAILQ_FIRST(&login->orbs); orbi != NULL; orbi = next) {
next = STAILQ_NEXT(orbi, link);
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
}
callout_stop(&login->hold_callout);
+
STAILQ_REMOVE(&login->lstate->logins, login, sbp_targ_login, link);
login->lstate->sc->logins[login->id] = NULL;
- if (debug)
- printf("%s: free login %p\n", __func__, login);
free((void *)login, M_SBP_TARG);
- login = NULL;
}
static void
@@ -312,25 +263,12 @@
login = (struct sbp_targ_login *)arg;
- /* if the login has been deallocated
- * prior to the login timeout, login
- * should be NULL, and we should do
- * nothing
- */
- if (login != NULL ) {
- if (login->flags & F_HOLD) {
- if (debug)
- printf("%s: login(%p), "
- "login_id=%d expired\n",
- __func__, login, login->id);
- sbp_targ_dealloc_login(login);
- } else if (debug) {
- printf("%s: login(%p), "
- "login_id=%d not hold\n",
- __func__, login, login->id);
- }
- } else if (debug)
- printf("%s: woke up and this login was NULL\n", __func__);
+ if (login->flags & F_HOLD) {
+ printf("%s: login_id=%d expired\n", __func__, login->id);
+ sbp_targ_dealloc_login(login);
+ } else {
+ printf("%s: login_id=%d not hold\n", __func__, login->id);
+ }
}
static void
@@ -353,8 +291,9 @@
if ((sc->flags & F_FREEZED) == 0) {
sc->flags |= F_FREEZED;
xpt_freeze_simq(sc->sim, /*count*/1);
- } else if (debug)
+ } else {
printf("%s: already freezed\n", __func__);
+ }
bzero(unit, sizeof(struct crom_chunk));
@@ -371,8 +310,6 @@
lstate = sc->lstate[i];
if (lstate == NULL)
continue;
- if (debug)
- printf("%s: lstate not null\n", __func__);
crom_add_entry(unit, CSRKEY_FIRM_VER, 1);
crom_add_entry(unit, CROM_LUN, i);
crom_add_entry(unit, CSRKEY_MODEL, 1);
@@ -382,25 +319,13 @@
/* Process for reconnection hold time */
for (i = 0; i < MAX_LOGINS; i ++) {
login = sc->logins[i];
- if (login == NULL) {
+ if (login == NULL)
continue;
- }
if (login->flags & F_LOGIN) {
- if (debug)
- printf("%s: setting sbp_targ_hold_expire "
- "for this login(%p)\n",
- __func__, login);
login->flags |= F_HOLD;
- login->flags &= ~F_LOGIN;
callout_reset(&login->hold_callout,
hz * login->hold_sec,
sbp_targ_hold_expire, (void *)login);
- } else if (debug) {
- /* Do nothing, allow sbp_Targ_hold_expire */
- /* to delete the login */
- printf("%s login->flags = %0x, "
- "not F_LOGIN\n",
- __func__, login->flags);
}
}
}
@@ -426,29 +351,20 @@
if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD &&
ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
*lstate = sc->black_hole;
- if (debug)
- printf("setting black hole for this target id(%d)\n",
- ccb->ccb_h.target_id);
return (CAM_REQ_CMP);
}
+ if (ccb->ccb_h.target_id != 0)
+ return (CAM_TID_INVALID);
+
lun = ccb->ccb_h.target_lun;
if (lun >= MAX_LUN)
return (CAM_LUN_INVALID);
*lstate = sc->lstate[lun];
- if (notfound_failure != 0 && *lstate == NULL) {
- if (debug)
- printf("%s: lstate for lun is invalid,"
- " target(%d), lun(%d)\n",
- __func__,
- ccb->ccb_h.target_id, lun);
+ if (notfound_failure != 0 && *lstate == NULL)
return (CAM_PATH_INVALID);
- } else
- if (debug)
- printf("%s: setting lstate for tgt(%d) lun(%d)\n",
- __func__,ccb->ccb_h.target_id, lun);
return (CAM_REQ_CMP);
}
@@ -485,20 +401,11 @@
printf("Couldn't allocate lstate\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
- } else {
- if (debug) {
- printf("%s: malloc'd lstate %p\n",
- __func__, lstate);
- }
- }
- if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) {
+ }
+ if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD)
sc->black_hole = lstate;
- if (debug)
- printf("Blackhole set due to target id == %d\n",
- ccb->ccb_h.target_id);
- } else
+ else
sc->lstate[ccb->ccb_h.target_lun] = lstate;
-
memset(lstate, 0, sizeof(*lstate));
lstate->sc = sc;
status = xpt_create_path(&lstate->path, /*periph*/NULL,
@@ -507,7 +414,6 @@
xpt_path_lun_id(ccb->ccb_h.path));
if (status != CAM_REQ_CMP) {
free(lstate, M_SBP_TARG);
- lstate = NULL;
xpt_print_path(ccb->ccb_h.path);
printf("Couldn't allocate path\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
@@ -527,7 +433,6 @@
if (lstate == NULL) {
ccb->ccb_h.status = CAM_LUN_INVALID;
- printf("Invalid lstate for this target\n");
return;
}
ccb->ccb_h.status = CAM_REQ_CMP;
@@ -543,7 +448,6 @@
}
if (ccb->ccb_h.status != CAM_REQ_CMP) {
- printf("status != CAM_REQ_CMP\n");
return;
}
@@ -561,15 +465,9 @@
sc->black_hole = NULL;
else
sc->lstate[ccb->ccb_h.target_lun] = NULL;
- if (debug)
- printf("%s: free lstate %p\n", __func__, lstate);
- if (lstate != NULL) {
- free(lstate, M_SBP_TARG);
- lstate = NULL;
- } else if (debug)
- printf("%s: lstate was null\n", __func__);
+ free(lstate, M_SBP_TARG);
+
/* bus reset */
-
sc->fd.fc->ibr(sc->fd.fc);
}
}
@@ -617,17 +515,10 @@
printf("%s: no such login\n", __func__);
return (NULL);
}
- STAILQ_FOREACH(orbi, &login->orbs, link) {
+ STAILQ_FOREACH(orbi, &login->orbs, link)
if (orbi->orb_lo == tag_id)
goto found;
- if ( orbi->state == ORBI_STATUS_ABORTED)
- printf("%s: orb aborted in flight tag_id=0x%08x\n",
- __func__, tag_id);
- else {
- panic("%s: orb not found tag_id=0x%08x, state(%0x)\n",
- __func__, tag_id, orbi->state);
- }
- }
+ printf("%s: orb not found tag_id=0x%08x\n", __func__, tag_id);
return (NULL);
found:
return (orbi);
@@ -639,8 +530,7 @@
struct orb_info *norbi;
for (; orbi != NULL; orbi = norbi) {
- printf("%s: status=%d ccb=%p\n",
- __func__, orbi->state, orbi->ccb);
+ printf("%s: status=%d\n", __func__, orbi->state);
norbi = STAILQ_NEXT(orbi, link);
if (orbi->state != ORBI_STATUS_ABORTED) {
if (orbi->ccb != NULL) {
@@ -650,12 +540,7 @@
}
if (orbi->state <= ORBI_STATUS_ATIO) {
sbp_targ_remove_orb_info(orbi->login, orbi);
- if (debug) {
- printf("%s: free orbi %p\n",
- __func__, orbi);
- }
free(orbi, M_SBP_TARG);
- orbi = NULL;
} else
orbi->state = ORBI_STATUS_ABORTED;
}
@@ -667,23 +552,12 @@
{
struct orb_info *orbi;
+ orbi = (struct orb_info *)xfer->sc;
if (xfer->resp != 0) {
/* XXX */
printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
}
-
- orbi = (struct orb_info *)xfer->sc;
- if ( orbi->page_table != NULL ) {
- if (debug)
- printf("%s: free orbi->page_table %p\n",
- __func__, orbi->page_table);
- free(orbi->page_table, M_SBP_TARG);
- orbi->page_table = NULL;
- }
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
fw_xfer_free(xfer);
}
@@ -692,14 +566,14 @@
uint32_t fifo_hi, uint32_t fifo_lo, int dequeue)
{
struct fw_xfer *xfer;
+
if (dequeue)
sbp_targ_remove_orb_info(orbi->login, orbi);
xfer = fwmem_write_block(orbi->fwdev, (void *)orbi,
- /*spd*/FWSPD_S400, fifo_hi, fifo_lo,
- sizeof(uint32_t) * (orbi->status.len + 1),
- (char *)&orbi->status,
- sbp_targ_free_orbi);
+ /*spd*/2, fifo_hi, fifo_lo,
+ sizeof(uint32_t) * (orbi->status.len + 1), (char *)&orbi->status,
+ sbp_targ_free_orbi);
if (xfer == NULL) {
/* XXX */
@@ -707,10 +581,6 @@
}
}
-/*
- * Generate the appropriate CAM status for the
- * target.
- */
static void
sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb)
{
@@ -724,7 +594,6 @@
sbp_status->status = 0; /* XXX */
sbp_status->dead = 0; /* XXX */
- ccb->ccb_h.status= CAM_REQ_CMP;
switch (ccb->csio.scsi_status) {
case SCSI_STATUS_OK:
if (debug)
@@ -732,22 +601,15 @@
sbp_status->len = 1;
break;
case SCSI_STATUS_CHECK_COND:
- if (debug)
- printf("%s: STATUS SCSI_STATUS_CHECK_COND\n", __func__);
- goto process_scsi_status;
case SCSI_STATUS_BUSY:
- if (debug)
- printf("%s: STATUS SCSI_STATUS_BUSY\n", __func__);
- goto process_scsi_status;
case SCSI_STATUS_CMD_TERMINATED:
- if (debug)
- printf("%s: STATUS SCSI_STATUS_CMD_TERMINATED\n",
- __func__);
-process_scsi_status:
{
struct sbp_cmd_status *sbp_cmd_status;
struct scsi_sense_data *sense;
+ if (debug)
+ printf("%s: STATUS %d\n", __func__,
+ ccb->csio.scsi_status);
sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0];
sbp_cmd_status->status = ccb->csio.scsi_status;
sense = &ccb->csio.sense_data;
@@ -784,7 +646,6 @@
bcopy(&sense->sense_key_spec[0],
&sbp_cmd_status->s_keydep[0], 3);
- ccb->ccb_h.status |= CAM_SENT_SENSE;
break;
}
default:
@@ -795,17 +656,10 @@
sbp_targ_status_FIFO(orbi,
orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1);
+ if (orbi->page_table != NULL)
+ free(orbi->page_table, M_SBP_TARG);
}
-/*
- * Invoked as a callback handler from fwmem_read/write_block
- *
- * Process read/write of initiator address space
- * completion and pass status onto the backend target.
- * If this is a partial read/write for a CCB then
- * we decrement the orbi's refcount to indicate
- * the status of the read/write is complete
- */
static void
sbp_targ_cam_done(struct fw_xfer *xfer)
{
@@ -814,9 +668,10 @@
orbi = (struct orb_info *)xfer->sc;
- if (debug)
+ if (debug > 1)
printf("%s: resp=%d refcount=%d\n", __func__,
xfer->resp, orbi->refcount);
+
if (xfer->resp != 0) {
printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
orbi->status.resp = SBP_TRANS_FAIL;
@@ -825,7 +680,7 @@
sbp_targ_abort(STAILQ_NEXT(orbi, link));
}
- orbi->refcount--;
+ orbi->refcount --;
ccb = orbi->ccb;
if (orbi->refcount == 0) {
@@ -833,31 +688,13 @@
if (debug)
printf("%s: orbi aborted\n", __func__);
sbp_targ_remove_orb_info(orbi->login, orbi);
- if (orbi->page_table != NULL) {
- if (debug)
- printf("%s: free orbi->page_table %p\n",
- __func__, orbi->page_table);
+ if (orbi->page_table != NULL)
free(orbi->page_table, M_SBP_TARG);
- orbi->page_table = NULL;
- }
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
- } else if (orbi->status.resp == ORBI_STATUS_NONE) {
- if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
- if (debug) {
- printf("%s: CAM_SEND_STATUS set %0x\n",
- __func__, ccb->ccb_h.flags);
- }
+ } else if (orbi->status.resp == 0) {
+ if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0)
sbp_targ_send_status(orbi, ccb);
- } else {
- if (debug) {
- printf("%s: CAM_SEND_STATUS !set %0x\n",
- __func__, ccb->ccb_h.flags);
- }
- ccb->ccb_h.status = CAM_REQ_CMP;
- }
+ ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
} else {
orbi->status.len = 1;
@@ -923,13 +760,6 @@
return (CAM_PATH_INVALID);
}
-/*
- * directly execute a read or write to the initiator
- * address space and set hand(sbp_targ_cam_done) to
- * process the completion from the SIM to the target.
- * set orbi->refcount to inidicate that a read/write
- * is inflight to/from the initiator.
- */
static void
sbp_targ_xfer_buf(struct orb_info *orbi, u_int offset,
uint16_t dst_hi, uint32_t dst_lo, u_int size,
@@ -948,24 +778,17 @@
/* XXX assume dst_lo + off doesn't overflow */
len = MIN(size, 2048 /* XXX */);
size -= len;
- orbi->refcount++;
- if (ccb_dir == CAM_DIR_OUT) {
- if (debug)
- printf("%s: CAM_DIR_OUT --> read block in?\n",
- __func__);
+ orbi->refcount ++;
+ if (ccb_dir == CAM_DIR_OUT)
xfer = fwmem_read_block(orbi->fwdev,
- (void *)orbi, /*spd*/FWSPD_S400,
+ (void *)orbi, /*spd*/2,
dst_hi, dst_lo + off, len,
ptr + off, hand);
- } else {
- if (debug)
- printf("%s: CAM_DIR_IN --> write block out?\n",
- __func__);
+ else
xfer = fwmem_write_block(orbi->fwdev,
- (void *)orbi, /*spd*/FWSPD_S400,
+ (void *)orbi, /*spd*/2,
dst_hi, dst_lo + off, len,
ptr + off, hand);
- }
if (xfer == NULL) {
printf("%s: xfer == NULL", __func__);
/* XXX what should we do?? */
@@ -979,24 +802,18 @@
sbp_targ_pt_done(struct fw_xfer *xfer)
{
struct orb_info *orbi;
- struct unrestricted_page_table_fmt *pt;
- uint32_t i;
+ union ccb *ccb;
+ u_int i, offset, res, len;
+ uint32_t t1, t2, *p;
orbi = (struct orb_info *)xfer->sc;
-
+ ccb = orbi->ccb;
if (orbi->state == ORBI_STATUS_ABORTED) {
if (debug)
printf("%s: orbi aborted\n", __func__);
sbp_targ_remove_orb_info(orbi->login, orbi);
- if (debug) {
- printf("%s: free orbi->page_table %p\n",
- __func__, orbi->page_table);
- printf("%s: free orbi %p\n", __func__, orbi);
- }
free(orbi->page_table, M_SBP_TARG);
- orbi->page_table = NULL;
free(orbi, M_SBP_TARG);
- orbi = NULL;
fw_xfer_free(xfer);
return;
}
@@ -1010,166 +827,58 @@
sbp_targ_status_FIFO(orbi,
orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1);
- if (debug)
- printf("%s: free orbi->page_table %p\n",
- __func__, orbi->page_table);
free(orbi->page_table, M_SBP_TARG);
- orbi->page_table = NULL;
fw_xfer_free(xfer);
return;
}
- orbi->refcount++;
- /*
- * Set endianess here so we don't have
- * to deal with is later
- */
- for (i = 0, pt = orbi->page_table; i < orbi->orb4.data_size; i++,pt++) {
- pt->segment_len = ntohs(pt->segment_len);
- if (debug)
- printf("%s:segment_len = %u\n",
- __func__,pt->segment_len);
- pt->segment_base_high = ntohs(pt->segment_base_high);
- pt->segment_base_low = ntohl(pt->segment_base_low);
+ res = ccb->csio.dxfer_len;
+ offset = 0;
+ if (debug)
+ printf("%s: dxfer_len=%d\n", __func__, res);
+ orbi->refcount ++;
+ for (p = orbi->page_table, i = orbi->orb4.data_size; i > 0; i --) {
+ t1 = ntohl(*p++);
+ t2 = ntohl(*p++);
+ if (debug > 1)
+ printf("page_table: %04x:%08x %d\n",
+ t1 & 0xffff, t2, t1>>16);
+ len = MIN(t1 >> 16, res);
+ res -= len;
+ sbp_targ_xfer_buf(orbi, offset, t1 & 0xffff, t2, len,
+ sbp_targ_cam_done);
+ offset += len;
+ if (res == 0)
+ break;
}
-
- sbp_targ_xfer_pt(orbi);
-
- orbi->refcount--;
+ orbi->refcount --;
if (orbi->refcount == 0)
printf("%s: refcount == 0\n", __func__);
+ if (res !=0)
+ /* XXX handle res != 0 case */
+ printf("%s: page table is too small(%d)\n", __func__, res);
+
fw_xfer_free(xfer);
return;
}
-static void sbp_targ_xfer_pt(struct orb_info *orbi)
-{
- union ccb *ccb;
- uint32_t res, offset, len;
-
- ccb = orbi->ccb;
- if (debug)
- printf("%s: dxfer_len=%d\n", __func__, ccb->csio.dxfer_len);
- res = ccb->csio.dxfer_len;
-
- /*
- * If the page table required multiple CTIO's to
- * complete, then cur_pte is non NULL
- * and we need to start from the last position
- * If this is the first pass over a page table
- * then we just start at the beginning of the page
- * table.
- *
- * Parse the unrestricted page table and figure out where we need
- * to shove the data from this read request.
- */
- for (offset = 0, len = 0;
- (res != 0) && (orbi->cur_pte < orbi->last_pte);
- offset += len) {
- len = MIN(orbi->cur_pte->segment_len, res);
- res -= len;
- if (debug)
- printf("%s:page_table: %04x:%08x segment_len(%u)"
- " res(%u) len(%u)\n",
- __func__, orbi->cur_pte->segment_base_high,
- orbi->cur_pte->segment_base_low,
- orbi->cur_pte->segment_len,
- res, len);
- sbp_targ_xfer_buf(orbi, offset,
- orbi->cur_pte->segment_base_high,
- orbi->cur_pte->segment_base_low,
- len, sbp_targ_cam_done);
- /*
- * If we have only written partially to
- * this page table, then we need to save
- * our position for the next CTIO. If we
- * have completed the page table, then we
- * are safe to move on to the next entry.
- */
- if (len == orbi->cur_pte->segment_len) {
- orbi->cur_pte++;
- } else {
- uint32_t saved_base_low;
-
- /* Handle transfers that cross a 4GB boundary. */
- saved_base_low = orbi->cur_pte->segment_base_low;
- orbi->cur_pte->segment_base_low += len;
- if (orbi->cur_pte->segment_base_low < saved_base_low)
- orbi->cur_pte->segment_base_high++;
-
- orbi->cur_pte->segment_len -= len;
- }
- }
- if (debug) {
- printf("%s: base_low(%08x) page_table_off(%p) last_block(%u)\n",
- __func__, orbi->cur_pte->segment_base_low,
- orbi->cur_pte, orbi->last_block_read);
- }
- if (res != 0)
- printf("Warning - short pt encountered. "
- "Could not transfer all data.\n");
- return;
-}
-
-/*
- * Create page table in local memory
- * and transfer it from the initiator
- * in order to know where we are supposed
- * to put the data.
- */
static void
sbp_targ_fetch_pt(struct orb_info *orbi)
{
struct fw_xfer *xfer;
- /*
- * Pull in page table from initiator
- * and setup for data from our
- * backend device.
- */
- if (orbi->page_table == NULL) {
- orbi->page_table = malloc(orbi->orb4.data_size*
- sizeof(struct unrestricted_page_table_fmt),
- M_SBP_TARG,
- M_NOWAIT|M_ZERO);
- if (orbi->page_table == NULL)
- goto error;
- orbi->cur_pte = orbi->page_table;
- orbi->last_pte = orbi->page_table + orbi->orb4.data_size;
- orbi->last_block_read = orbi->orb4.data_size;
- if (debug && orbi->page_table != NULL)
- printf("%s: malloc'd orbi->page_table(%p),"
- " orb4.data_size(%u)\n",
- __func__,
- orbi->page_table,
- orbi->orb4.data_size);
-
- xfer = fwmem_read_block(orbi->fwdev, (void *)orbi,
- /*spd*/FWSPD_S400, orbi->data_hi,
- orbi->data_lo, orbi->orb4.data_size*
- sizeof(struct unrestricted_page_table_fmt),
- (void *)orbi->page_table, sbp_targ_pt_done);
-
- if (xfer != NULL)
- return;
- } else {
- /*
- * This is a CTIO for a page table we have
- * already malloc'd, so just directly invoke
- * the xfer function on the orbi.
- */
- sbp_targ_xfer_pt(orbi);
-
+ if (debug)
+ printf("%s: page_table_size=%d\n",
+ __func__, orbi->orb4.data_size);
+ orbi->page_table = malloc(orbi->orb4.data_size*8, M_SBP_TARG, M_NOWAIT);
+ if (orbi->page_table == NULL)
+ goto error;
+ xfer = fwmem_read_block(orbi->fwdev, (void *)orbi, /*spd*/2,
+ orbi->data_hi, orbi->data_lo, orbi->orb4.data_size*8,
+ (void *)orbi->page_table, sbp_targ_pt_done);
+ if (xfer != NULL)
return;
- }
error:
orbi->ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
- if (debug)
- printf("%s: free orbi->page_table %p due to xfer == NULL\n",
- __func__, orbi->page_table);
- if (orbi->page_table != NULL) {
- free(orbi->page_table, M_SBP_TARG);
- orbi->page_table = NULL;
- }
xpt_done(orbi->ccb);
return;
}
@@ -1192,8 +901,7 @@
struct orb_info *orbi;
if (debug)
- printf("%s: XPT_CONT_TARGET_IO(0x%08x)\n",
- __func__, ccb->csio.tag_id);
+ printf("%s: XPT_CONT_TARGET_IO\n", __func__);
if (status != CAM_REQ_CMP) {
ccb->ccb_h.status = status;
@@ -1212,12 +920,7 @@
if (debug)
printf("%s: ctio aborted\n", __func__);
sbp_targ_remove_orb_info(orbi->login, orbi);
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
- ccb->ccb_h.status = CAM_REQ_ABORTED;
- xpt_done(ccb);
break;
}
orbi->state = ORBI_STATUS_CTIO;
@@ -1249,30 +952,23 @@
break;
}
- if (ccb_dir != CAM_DIR_NONE) {
+ /* Sanity check */
+ if (ccb_dir != CAM_DIR_NONE &&
+ orbi->orb4.data_size != ccb->csio.dxfer_len)
+ printf("%s: data_size(%d) != dxfer_len(%d)\n",
+ __func__, orbi->orb4.data_size,
+ ccb->csio.dxfer_len);
+
+ if (ccb_dir != CAM_DIR_NONE)
sbp_targ_xfer_buf(orbi, 0, orbi->data_hi,
orbi->data_lo,
MIN(orbi->orb4.data_size, ccb->csio.dxfer_len),
sbp_targ_cam_done);
- if ( orbi->orb4.data_size > ccb->csio.dxfer_len ) {
- orbi->data_lo += ccb->csio.dxfer_len;
- orbi->orb4.data_size -= ccb->csio.dxfer_len;
- }
- }
-
if (ccb_dir == CAM_DIR_NONE) {
- if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
- if (debug)
- printf("%s: CAM_SEND_STATUS set %0x\n",
- __func__, ccb->ccb_h.flags);
+ if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0)
sbp_targ_send_status(orbi, ccb);
- } else {
- if (debug)
- printf("%s: CAM_SEND_STATUS !set %0x\n",
- __func__, ccb->ccb_h.flags);
- ccb->ccb_h.status = CAM_REQ_CMP;
- }
+ ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
}
break;
@@ -1327,9 +1023,7 @@
cpi->target_sprt = PIT_PROCESSOR
| PIT_DISCONNECT
| PIT_TERM_IO;
- cpi->transport = XPORT_FW;
- cpi->hba_misc = PIM_NOINITIATOR
- | PIM_NOBUSRESET;
+ cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
cpi->hba_eng_cnt = 0;
cpi->max_target = 7; /* XXX */
cpi->max_lun = MAX_LUN - 1;
@@ -1367,39 +1061,10 @@
xpt_done(ccb);
break;
}
- case XPT_SET_TRAN_SETTINGS:
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &ccb->cts;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
-
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_FW; /* should have a FireWire */
- cts->transport_version = 2;
- spi->valid = CTS_SPI_VALID_DISC;
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- scsi->valid = CTS_SCSI_VALID_TQ;
- scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
-#if 0
- printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:\n",
- device_get_nameunit(sc->fd.dev),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
-#endif
- cts->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
default:
- printf("%s: unknown function 0x%x\n",
+ printf("%s: unknown function %d\n",
__func__, ccb->ccb_h.func_code);
- ccb->ccb_h.status = CAM_PROVIDE_FAIL;
+ ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
break;
}
@@ -1450,17 +1115,10 @@
}
fp = &xfer->recv.hdr;
- atio = orbi->atio;
-
if (orbi->state == ORBI_STATUS_ABORTED) {
printf("%s: aborted\n", __func__);
sbp_targ_remove_orb_info(orbi->login, orbi);
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
- atio->ccb_h.status = CAM_REQ_ABORTED;
- xpt_done((union ccb*)atio);
goto done0;
}
orbi->state = ORBI_STATUS_ATIO;
@@ -1476,21 +1134,21 @@
printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt);
}
+ atio = orbi->atio;
atio->ccb_h.target_id = 0; /* XXX */
atio->ccb_h.target_lun = orbi->login->lstate->lun;
atio->sense_len = 0;
- atio->tag_action = MSG_SIMPLE_TASK;
+ atio->tag_action = 1; /* XXX */
atio->tag_id = orbi->orb_lo;
atio->init_id = orbi->login->id;
atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
- bytes = (u_char *)&orb[5];
+ bytes = (char *)&orb[5];
if (debug)
- printf("%s: %p %02x %02x %02x %02x %02x"
- " %02x %02x %02x %02x %02x\n",
- __func__, (void *)atio,
- bytes[0], bytes[1], bytes[2], bytes[3], bytes[4],
- bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]);
+ printf("%s: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ __func__,
+ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4],
+ bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]);
switch (bytes[0] >> 5) {
case 0:
atio->cdb_len = 6;
@@ -1549,25 +1207,8 @@
lstate = sc->lstate[lun];
STAILQ_FOREACH(login, &lstate->logins, link)
- if (login->fwdev == fwdev) {
- /*
- * We are receiving a login from
- * an initiator that left and didn't
- * logout properly. We need to kill
- * the callout before returning the
- * login struct to the caller.
- * For 7.X and higher, this is not safe
- * and will need to be protected by
- * a lock.
- * For 6.X we are safe as we hold Giant
- * and the callout must aquire Giant.
- */
- if (!(callout_stop(&login->hold_callout)) && (debug))
- printf("%s:callout in progress for login(%p)\n",
- __func__, login);
- login->flags |= F_RECYCLE_LOGIN;
+ if (login->fwdev == fwdev)
return (login);
- }
for (i = 0; i < MAX_LOGINS; i ++)
if (sc->logins[i] == NULL)
@@ -1583,8 +1224,6 @@
if (login == NULL) {
printf("%s: malloc failed\n", __func__);
return (NULL);
- } else if (debug) {
- printf("%s: malloc'd login %p\n", __func__, login);
}
login->id = i;
@@ -1592,9 +1231,7 @@
login->lstate = lstate;
login->last_hi = 0xffff;
login->last_lo = 0xffffffff;
- login->hold_sec = SBP_TARG_HOLD_TIMEOUT;
- login->flags |= F_LOGIN ;
- login->flags &= ~F_RECYCLE_LOGIN ;
+ login->hold_sec = 1;
STAILQ_INIT(&login->orbs);
CALLOUT_INIT(&login->hold_callout);
sc->logins[i] = login;
@@ -1609,7 +1246,7 @@
struct fw_pkt *fp;
uint32_t *orb;
struct morb4 *orb4;
- struct orb_info *orbi, *aborted_orb = NULL;
+ struct orb_info *orbi;
int i;
orbi = (struct orb_info *)xfer->sc;
@@ -1633,7 +1270,7 @@
for (i = 0; i < 8; i ++) {
orb[i] = ntohl(orb[i]);
}
- orb4 = (struct morb4 *)&orb;
+ orb4 = (struct morb4 *)&orb[4];
if (debug)
printf("%s: %s\n", __func__, orb_fun_name[orb4->fun]);
@@ -1650,10 +1287,11 @@
lun = orb4->id;
lstate = orbi->sc->lstate[lun];
- if (lun >= MAX_LUN || lstate == NULL
- || (exclusive
- && STAILQ_FIRST(&lstate->logins) != NULL
- && STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev)) {
+ if (lun >= MAX_LUN || lstate == NULL ||
+ (exclusive &&
+ STAILQ_FIRST(&lstate->logins) != NULL &&
+ STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev)
+ ) {
/* error */
orbi->status.dead = 1;
orbi->status.status = STATUS_ACCESS_DENY;
@@ -1672,8 +1310,6 @@
break;
}
- printf("%s: New login(%p), login id=%d\n",
- __func__, login, login->id);
login->fifo_hi = orb[6];
login->fifo_lo = orb[7];
login->loginres.len = htons(sizeof(uint32_t) * 4);
@@ -1682,30 +1318,10 @@
login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id));
login->loginres.recon_hold = htons(login->hold_sec);
- fwmem_write_block(orbi->fwdev, NULL, /*spd*/FWSPD_S400, orb[2],
- orb[3], sizeof(struct sbp_login_res),
- (void *)&login->loginres, fw_asy_callback_free);
- /*
- * If this is a new initiator and a login
- * was recycled, then it is already in the
- * login STAILQ, don't re-insert it.
- */
- if (login->flags & F_RECYCLE_LOGIN) {
- if (debug)
- printf("%s: login(%p) already in STAILQ,"
- " flags(%0x) no reinsertion needed\n",
- __func__, login, login->flags);
- /*
- * Clear RECYCLE flag
- */
- login->flags &= ~F_RECYCLE_LOGIN;
- } else {
- if (debug)
- printf("%s: login(%p) not in STAILQ,"
- " inserting\n", __func__, login);
- STAILQ_INSERT_TAIL(&lstate->logins, login, link);
- }
-
+ fwmem_write_block(orbi->fwdev, NULL, /*spd*/2, orb[2], orb[3],
+ sizeof(struct sbp_login_res), (void *)&login->loginres,
+ fw_asy_callback_free);
+ STAILQ_INSERT_TAIL(&lstate->logins, login, link);
/* XXX return status after loginres is successfully written */
break;
}
@@ -1714,7 +1330,6 @@
if (login != NULL && login->fwdev == orbi->fwdev) {
login->flags &= ~F_HOLD;
callout_stop(&login->hold_callout);
- login->flags |= F_LOGIN;
printf("%s: reconnected id=%d\n",
__func__, login->id);
} else {
@@ -1732,44 +1347,6 @@
}
sbp_targ_dealloc_login(login);
break;
- case ORB_FUN_ATA: /* TODO */
- /*
- * Find the orb to be aborted.
- * If we haven't fetched, just drop it on the floor.
- * If we have already fetched,
- * process normally and don't worry about it.
- */
- printf("%s: Abort Task recieved\n", __func__);
- login = orbi->sc->logins[orb4->id];
- STAILQ_FOREACH(aborted_orb, &login->orbs, link) {
- if (aborted_orb->orb_lo == (orb4->off_lo >> 2))
- sbp_targ_abort(aborted_orb);
- else {
- panic("%s: orb not found"
- " aborted_orb->orb_lo=0x%08x,"
- " orb4->off_lo(%0x)\n",
- __func__, aborted_orb->orb_lo,
- (orb4->off_lo >> 2));
- }
- }
- break;
- case ORB_FUN_ATS: /* TODO */
- printf("%s: Abort Task Set recieved for orb\n",__func__ );
- login = orbi->sc->logins[orb4->id];
- STAILQ_FOREACH(aborted_orb, &login->orbs, link) {
- if (aborted_orb != NULL) {
- printf("%s: aborting orb\n", __func__);
- sbp_targ_abort(aborted_orb);
- }
- }
- printf("%s: all orb aborted\n", __func__);
- break;
- case ORB_FUN_LUR: /* TODO */
- printf("%s: Logical Unit Reset recieved for orb\n",__func__);
- break;
- case ORB_FUN_RST: /* TODO */
- printf("%s: Target Reset recieved for orb\n", __func__);
- break;
default:
printf("%s: %s not implemented yet\n",
__func__, orb_fun_name[orb4->fun]);
@@ -1802,10 +1379,7 @@
sbp_targ_fetch_orb(orbi->login->lstate->sc, orbi->fwdev,
(uint16_t)orb0, orb1, orbi->login, FETCH_CMD);
done:
- if (debug)
- printf("%s: free orbi %p\n", __func__, orbi);
free(orbi, M_SBP_TARG);
- orbi = NULL;
fw_xfer_free(xfer);
return;
}
@@ -1818,14 +1392,11 @@
struct orb_info *orbi;
if (debug)
- printf("%s: fetch orb mode %d, %04x:%08x\n",
- __func__, mode, orb_hi, orb_lo);
+ printf("%s: fetch orb %04x:%08x\n", __func__, orb_hi, orb_lo);
orbi = malloc(sizeof(struct orb_info), M_SBP_TARG, M_NOWAIT | M_ZERO);
if (orbi == NULL) {
printf("%s: malloc failed\n", __func__);
return;
- } else if (debug) {
- printf("%s: malloc'd orbi %p\n", __func__, orbi);
}
orbi->sc = sc;
orbi->fwdev = fwdev;
@@ -1834,20 +1405,14 @@
orbi->orb_lo = orb_lo;
orbi->status.orb_hi = htons(orb_hi);
orbi->status.orb_lo = htonl(orb_lo);
- orbi->page_table = NULL;
switch (mode) {
case FETCH_MGM:
- if (debug)
- printf("%s: FETCH_MGM for orbi %p\n", __func__, orbi);
- fwmem_read_block(fwdev, (void *)orbi,
- /*spd*/FWSPD_S400, orb_hi, orb_lo,
- sizeof(uint32_t) * 8, &orbi->orb[0],
+ fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo,
+ sizeof(uint32_t) * 8, &orbi->orb[0],
sbp_targ_mgm_handler);
break;
case FETCH_CMD:
- if (debug)
- printf("%s: FETCH_CMD for orbi %p\n", __func__, orbi);
orbi->state = ORBI_STATUS_FETCH;
login->last_hi = orb_hi;
login->last_lo = orb_lo;
@@ -1866,22 +1431,17 @@
break;
}
SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle);
- fwmem_read_block(fwdev, (void *)orbi,
- /*spd*/FWSPD_S400, orb_hi, orb_lo,
- sizeof(uint32_t) * 8, &orbi->orb[0],
- sbp_targ_cmd_handler);
+ fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo,
+ sizeof(uint32_t) * 8, &orbi->orb[0],
+ sbp_targ_cmd_handler);
STAILQ_INSERT_TAIL(&login->orbs, orbi, link);
break;
case FETCH_POINTER:
- if (debug)
- printf("%s: FETCH_POINTER for orbi %p\n",
- __func__, orbi);
orbi->state = ORBI_STATUS_POINTER;
login->flags |= F_LINK_ACTIVE;
- fwmem_read_block(fwdev, (void *)orbi,
- /*spd*/FWSPD_S400, orb_hi, orb_lo,
- sizeof(uint32_t) * 2, &orbi->orb[0],
- sbp_targ_pointer_handler);
+ fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo,
+ sizeof(uint32_t) * 2, &orbi->orb[0],
+ sbp_targ_pointer_handler);
break;
default:
printf("%s: invalid mode %d\n", __func__, mode);
@@ -1911,13 +1471,11 @@
{
struct sbp_targ_login *login;
struct sbp_targ_softc *sc;
- struct orb_info *unsolicited_orbi;
int rtcode = 0;
if (login_id < 0 || login_id >= MAX_LOGINS)
return(RESP_ADDRESS_ERROR);
- printf("%s: made it here\n",__func__);
sc = (struct sbp_targ_softc *)xfer->sc;
login = sc->logins[login_id];
if (login == NULL)
@@ -1931,7 +1489,7 @@
switch (reg) {
case 0x08: /* ORB_POINTER */
if (debug)
- printf("%s: ORB_POINTER (%d)\n", __func__, login_id);
+ printf("%s: ORB_POINTER\n", __func__);
if ((login->flags & F_LINK_ACTIVE) != 0) {
if (debug)
printf("link active (ORB_POINTER)\n");
@@ -1944,14 +1502,14 @@
break;
case 0x04: /* AGENT_RESET */
if (debug)
- printf("%s: AGENT RESET (%d)\n", __func__, login_id);
+ printf("%s: AGENT RESET\n", __func__);
login->last_hi = 0xffff;
login->last_lo = 0xffffffff;
sbp_targ_abort(STAILQ_FIRST(&login->orbs));
break;
case 0x10: /* DOORBELL */
if (debug)
- printf("%s: DOORBELL (%d)\n", __func__, login_id);
+ printf("%s: DOORBELL\n", __func__);
if (login->last_hi == 0xffff &&
login->last_lo == 0xffffffff) {
printf("%s: no previous pointer(DOORBELL)\n",
@@ -1968,58 +1526,19 @@
login, FETCH_POINTER);
break;
case 0x00: /* AGENT_STATE */
- printf("%s: AGENT_STATE (%d)\n", __func__, login_id);
- sbp_targ_send_agent_state(xfer);
+ printf("%s: AGENT_STATE (ignore)\n", __func__);
break;
case 0x14: /* UNSOLICITED_STATE_ENABLE */
- printf("%s: UNSOLICITED_STATE_ENABLE (%d)\n",
- __func__, login_id);
- unsolicited_orbi = malloc(sizeof(struct orb_info),
- M_SBP_TARG,
- M_NOWAIT | M_ZERO);
- unsolicited_orbi->fwdev = login->fwdev;
- unsolicited_orbi->status.src = SRC_UNSOL;
- unsolicited_orbi->status.resp = SBP_REQ_CMP;
- sbp_targ_status_FIFO(unsolicited_orbi,
- login->fifo_hi,
- login->fifo_lo,
- /*No dequeue*/0);
+ printf("%s: UNSOLICITED_STATE_ENABLE (ignore)\n", __func__);
break;
default:
- printf("%s: invalid register %d(%d)\n",
- __func__, reg, login_id);
+ printf("%s: invalid register %d\n", __func__, reg);
rtcode = RESP_ADDRESS_ERROR;
}
return (rtcode);
}
-static void
-sbp_targ_send_agent_state(struct fw_xfer *xfer)
-{
- struct agent_state *current_state;
- struct fw_pkt *rfp; /* response to request --> from target */
-
- xfer->send.payload = malloc(sizeof(struct agent_state),
- M_SBP_TARG,
- M_NOWAIT | M_ZERO);
- xfer->send.pay_len = ntohs(sizeof(struct agent_state));
- xfer->send.spd = FWSPD_S400;
-
- current_state = (struct agent_state *)xfer->send.payload;
- current_state->fetch_agent_state = AGENT_STATE_ACTIVE;
-
- rfp = &xfer->recv.hdr;
- rfp->mode.rresb.tcode = FWTCODE_RRESB;
- rfp->mode.rresb.rtcode = 0;
- rfp->mode.rresb.extcode = 0;
- xfer->send.hdr.mode.hdr.dst = ntohs(rfp->mode.hdr.src);
- xfer->hand = fw_xfer_free_buf;
- rfp->mode.hdr.pri = 0;
- fw_asyreq(xfer->fc, -1, xfer);
-
-}
-
static int
sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev)
{
@@ -2048,7 +1567,7 @@
{
struct fw_pkt *fp, *sfp;
struct fw_device *fwdev;
- uint32_t lo = 0;
+ uint32_t lo;
int s, rtcode;
struct sbp_targ_softc *sc;
@@ -2060,22 +1579,22 @@
printf("%s: cannot resolve nodeid=%d\n",
__func__, fp->mode.wreqb.src & 0x3f);
rtcode = RESP_TYPE_ERROR; /* XXX */
- } else {
- lo = fp->mode.wreqb.dest_lo;
- if (lo == SBP_TARG_BIND_LO(-1))
- rtcode = sbp_targ_mgm(xfer, fwdev);
- else if (lo >= SBP_TARG_BIND_LO(0))
- rtcode = sbp_targ_cmd(xfer, fwdev,
- SBP_TARG_LOGIN_ID(lo),
- lo % 0x20);
- else
- rtcode = RESP_ADDRESS_ERROR;
+ goto done;
}
+ lo = fp->mode.wreqb.dest_lo;
+ if (lo == SBP_TARG_BIND_LO(-1))
+ rtcode = sbp_targ_mgm(xfer, fwdev);
+ else if (lo >= SBP_TARG_BIND_LO(0))
+ rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo),
+ lo % 0x20);
+ else
+ rtcode = RESP_ADDRESS_ERROR;
+done:
if (rtcode != 0)
- printf("%s: rtcode = %d lo == 0x%x\n", __func__, rtcode, lo);
+ printf("%s: rtcode = %d\n", __func__, rtcode);
sfp = &xfer->send.hdr;
- xfer->send.spd = FWSPD_S400;
+ xfer->send.spd = 2; /* XXX */
xfer->hand = sbp_targ_resp_callback;
sfp->mode.wres.dst = fp->mode.wreqb.src;
sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt;
@@ -2096,8 +1615,6 @@
sc = (struct sbp_targ_softc *) device_get_softc(dev);
bzero((void *)sc, sizeof(struct sbp_targ_softc));
-
-
sc->fd.fc = device_get_ivars(dev);
sc->fd.dev = dev;
sc->fd.post_explore = (void *) sbp_targ_post_explore;
@@ -2133,23 +1650,6 @@
/*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */,
sc->fd.fc, (void *)sc, sbp_targ_recv);
fw_bindadd(sc->fd.fc, &sc->fwb);
- /*
- * setup CSR for BUSY_TIMEOUT from
- * initiator(0x210)
- */
- fwcsr_busy_timeout_init(&sc->busy_timeout, &sc->fd, sc,
- M_SBP_TARG, 0,
- SBP_TARG_RECV_LEN,
- MAX_LUN);
-#if 0
- sc->busy_timeout.start = 0xfffff0000000 | BUSY_TIMEOUT;
- sc->busy_timeout.end = 0xfffff0000000 | BUSY_TIMEOUT;
- STAILQ_INIT(&sc->busy_timeout.xferlist);
- fw_xferlist_add(&sc->busy_timeout.xferlist, M_SBP_TARG,
- /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */,
- sc->fd.fc, (void *)sc, sbp_targ_busy_timeout);
- fw_bindadd(sc->fd.fc, &sc->busy_timeout);
-#endif
return 0;
fail:
@@ -2175,30 +1675,17 @@
lstate = sc->lstate[i];
if (lstate != NULL) {
xpt_free_path(lstate->path);
- if (debug) {
- printf("%s: lstate free %p\n",
- __func__, lstate);
- }
free(lstate, M_SBP_TARG);
- lstate = NULL;
}
}
if (sc->black_hole != NULL) {
xpt_free_path(sc->black_hole->path);
- if (debug) {
- printf("%s: free blackhole? %p\n",
- __func__, sc->black_hole);
- }
free(sc->black_hole, M_SBP_TARG);
- sc->black_hole = NULL;
}
fw_bindremove(sc->fd.fc, &sc->fwb);
fw_xferlist_remove(&sc->fwb.xferlist);
- fw_bindremove(sc->fd.fc, &sc->busy_timeout);
- fwcsr_busy_timeout_stop(&sc->busy_timeout, &sc->fd);
-
return 0;
}
Index: firewire.c
===================================================================
--- firewire.c (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ firewire.c (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -285,7 +285,7 @@
return;
}
#endif
- microuptime(&xfer->tv);
+ microtime(&xfer->tv);
s = splfw();
xfer->state = FWXF_INQ;
STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
@@ -315,51 +315,40 @@
{
struct fw_xfer *xfer;
struct timeval tv;
- struct timeval now;
struct timeval split_timeout;
int i, s;
split_timeout.tv_sec = 0;
split_timeout.tv_usec = 200 * 1000; /* 200 msec */
- microuptime(&tv);
- if (timevalcmp(&split_timeout, &tv, >)) {
- /* we haven't been awake long enough, come back later */
- } else {
- now.tv_sec = tv.tv_sec;
- now.tv_usec = tv.tv_usec;
- timevalsub(&tv, &split_timeout);
+ microtime(&tv);
+ timevalsub(&tv, &split_timeout);
- s = splfw();
- for (i = 0; i < 0x40; i ++) {
- while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
- if (timevalcmp(&xfer->tv, &tv, >))
- /* the rests are newer than this */
- break;
- if (xfer->state == FWXF_START)
- /* not sent yet */
- break;
- device_printf(fc->bdev,
- "split transaction timeout dst=0x%x tl=0x%x state=%d\n"
- "xfer->tv(%ld,%ld) tv(%ld,%ld), now(%ld,%ld)\n",
- xfer->send.hdr.mode.hdr.dst, i, xfer->state,
- xfer->tv.tv_sec, xfer->tv.tv_usec,
- tv.tv_sec, tv.tv_usec,
- now.tv_sec, now.tv_usec);
- xfer->resp = ETIMEDOUT;
- fw_xfer_done(xfer);
- }
+ s = splfw();
+ for (i = 0; i < 0x40; i ++) {
+ while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
+ if (timevalcmp(&xfer->tv, &tv, >))
+ /* the rests are newer than this */
+ break;
+ if (xfer->state == FWXF_START)
+ /* not sent yet */
+ break;
+ device_printf(fc->bdev,
+ "split transaction timeout dst=0x%x tl=0x%x state=%d\n",
+ xfer->send.hdr.mode.hdr.dst, i, xfer->state);
+ xfer->resp = ETIMEDOUT;
+ fw_xfer_done(xfer);
}
- splx(s);
}
+ splx(s);
}
-#define WATCHDOG_HZ 10
+#define WATCHDOC_HZ 10
static void
firewire_watchdog(void *arg)
{
struct firewire_comm *fc;
- static int watchdog_clock = 0;
+ static int watchdoc_clock = 0;
fc = (struct firewire_comm *)arg;
@@ -368,13 +357,13 @@
* We encounter a timeout easily. To avoid this,
* ignore clock interrupt for a while.
*/
- if (watchdog_clock > WATCHDOG_HZ * 15) {
+ if (watchdoc_clock > WATCHDOC_HZ * 15) {
firewire_xfer_timeout(fc);
fc->timeout(fc);
} else
- watchdog_clock ++;
+ watchdoc_clock ++;
- callout_reset(&fc->timeout_callout, hz / WATCHDOG_HZ,
+ callout_reset(&fc->timeout_callout, hz / WATCHDOC_HZ,
(void *)firewire_watchdog, (void *)fc);
}
@@ -638,7 +627,7 @@
crom_add_simple_text(src, root, &buf->vendor, "DragonFly Project");
crom_add_entry(root, CSRKEY_HW, __DragonFly_cc_version);
#else
- crom_add_simple_text(src, root, &buf->vendor, "Miralink");
+ crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project");
crom_add_entry(root, CSRKEY_HW, __FreeBSD_version);
#endif
crom_add_simple_text(src, root, &buf->hw, hostname);
Index: sbp.c
===================================================================
--- sbp.c (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ sbp.c (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -2523,24 +2523,15 @@
case XPT_GET_TRAN_SETTINGS:
{
struct ccb_trans_settings *cts = &ccb->cts;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
-
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_SPI; /* should have a FireWire */
- cts->transport_version = 2;
- spi->valid = CTS_SPI_VALID_DISC;
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- scsi->valid = CTS_SCSI_VALID_TQ;
- scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
SBP_DEBUG(1)
printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
device_get_nameunit(sbp->fd.dev),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
END_DEBUG
+ /* Enable disconnect and tagged queuing */
+ cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
+ cts->flags = CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB;
+
cts->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
Index: sbp.h
===================================================================
--- sbp.h (.../miralink.FreeBSD.6/src/sys/dev/firewire) (revision 5436)
+++ sbp.h (.../FreeBSD_RELENG_6_13APR07/src/sys/dev/firewire) (revision 5436)
@@ -103,18 +103,12 @@
uint32_t orb_lo;
uint32_t data[6];
};
-/*
- * Values for src
- * From sbp-2 5.3
- */
+/* src */
#define SRC_NEXT_EXISTS 0
#define SRC_NO_NEXT 1
#define SRC_UNSOL 2
-/*
- * Values for resp.
- * From sbp-2 5.3
- */
+/* resp */
#define SBP_REQ_CMP 0 /* request complete */
#define SBP_TRANS_FAIL 1 /* transport failure */
#define SBP_ILLE_REQ 2 /* illegal request */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4835AC29.4030802>
