Deleted Added
full compact
sbp.c (266270) sbp.c (266772)
1/*-
2 * Copyright (c) 2003 Hidetoshi Shimokawa
3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the acknowledgement as bellow:
16 *
17 * This product includes software developed by K. Kobayashi and H. Shimokawa
18 *
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
1/*-
2 * Copyright (c) 2003 Hidetoshi Shimokawa
3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the acknowledgement as bellow:
16 *
17 * This product includes software developed by K. Kobayashi and H. Shimokawa
18 *
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * $FreeBSD: head/sys/dev/firewire/sbp.c 266270 2014-05-16 21:19:17Z brueffer $
34 * $FreeBSD: head/sys/dev/firewire/sbp.c 266772 2014-05-27 19:56:02Z jhb $
35 *
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/module.h>
41#include <sys/bus.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>
44#include <machine/bus.h>
45#include <sys/malloc.h>
46#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
47#include <sys/lock.h>
48#include <sys/mutex.h>
49#endif
50
51#if defined(__DragonFly__) || __FreeBSD_version < 500106
52#include <sys/devicestat.h> /* for struct devstat */
53#endif
54
55#ifdef __DragonFly__
56#include <bus/cam/cam.h>
57#include <bus/cam/cam_ccb.h>
58#include <bus/cam/cam_sim.h>
59#include <bus/cam/cam_xpt_sim.h>
60#include <bus/cam/cam_debug.h>
61#include <bus/cam/cam_periph.h>
62#include <bus/cam/scsi/scsi_all.h>
63
64#include <bus/firewire/firewire.h>
65#include <bus/firewire/firewirereg.h>
66#include <bus/firewire/fwdma.h>
67#include <bus/firewire/iec13213.h>
68#include "sbp.h"
69#else
70#include <cam/cam.h>
71#include <cam/cam_ccb.h>
72#include <cam/cam_sim.h>
73#include <cam/cam_xpt_sim.h>
74#include <cam/cam_debug.h>
75#include <cam/cam_periph.h>
76#include <cam/scsi/scsi_all.h>
77
78#include <dev/firewire/firewire.h>
79#include <dev/firewire/firewirereg.h>
80#include <dev/firewire/fwdma.h>
81#include <dev/firewire/iec13213.h>
82#include <dev/firewire/sbp.h>
83#endif
84
85#define ccb_sdev_ptr spriv_ptr0
86#define ccb_sbp_ptr spriv_ptr1
87
88#define SBP_NUM_TARGETS 8 /* MAX 64 */
89/*
90 * Scan_bus doesn't work for more than 8 LUNs
91 * because of CAM_SCSI2_MAXLUN in cam_xpt.c
92 */
93#define SBP_NUM_LUNS 64
94#define SBP_MAXPHYS MIN(MAXPHYS, (512*1024) /* 512KB */)
95#define SBP_DMA_SIZE PAGE_SIZE
96#define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
97#define SBP_QUEUE_LEN ((SBP_DMA_SIZE - SBP_LOGIN_SIZE) / sizeof(struct sbp_ocb))
98#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
99
100/*
101 * STATUS FIFO addressing
102 * bit
103 * -----------------------
104 * 0- 1( 2): 0 (alignment)
105 * 2- 7( 6): target
106 * 8-15( 8): lun
107 * 16-31( 8): reserved
108 * 32-47(16): SBP_BIND_HI
109 * 48-64(16): bus_id, node_id
110 */
111#define SBP_BIND_HI 0x1
112#define SBP_DEV2ADDR(t, l) \
113 (((u_int64_t)SBP_BIND_HI << 32) \
114 | (((l) & 0xff) << 8) \
115 | (((t) & 0x3f) << 2))
116#define SBP_ADDR2TRG(a) (((a) >> 2) & 0x3f)
117#define SBP_ADDR2LUN(a) (((a) >> 8) & 0xff)
118#define SBP_INITIATOR 7
119
120static char *orb_fun_name[] = {
121 ORB_FUN_NAMES
122};
123
124static int debug = 0;
125static int auto_login = 1;
126static int max_speed = -1;
127static int sbp_cold = 1;
128static int ex_login = 1;
129static int login_delay = 1000; /* msec */
130static int scan_delay = 500; /* msec */
131static int use_doorbell = 0;
132static int sbp_tags = 0;
133
134SYSCTL_DECL(_hw_firewire);
135static SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0,
136 "SBP-II Subsystem");
137SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
138 "SBP debug flag");
139SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
140 "SBP perform login automatically");
141SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
142 "SBP transfer max speed");
143SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
144 &ex_login, 0, "SBP enable exclusive login");
145SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
146 &login_delay, 0, "SBP login delay in msec");
147SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
148 &scan_delay, 0, "SBP scan delay in msec");
149SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, use_doorbell, CTLFLAG_RW,
150 &use_doorbell, 0, "SBP use doorbell request");
151SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, tags, CTLFLAG_RW, &sbp_tags, 0,
152 "SBP tagged queuing support");
153
154TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
155TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
156TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
157TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
158TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
159TUNABLE_INT("hw.firewire.sbp.use_doorbell", &use_doorbell);
160TUNABLE_INT("hw.firewire.sbp.tags", &sbp_tags);
161
162#define NEED_RESPONSE 0
163
164#define SBP_SEG_MAX rounddown(0xffff, PAGE_SIZE)
165#ifdef __sparc64__ /* iommu */
166#define SBP_IND_MAX howmany(SBP_MAXPHYS, SBP_SEG_MAX)
167#else
168#define SBP_IND_MAX howmany(SBP_MAXPHYS, PAGE_SIZE)
169#endif
170struct sbp_ocb {
171 STAILQ_ENTRY(sbp_ocb) ocb;
172 union ccb *ccb;
173 bus_addr_t bus_addr;
174 uint32_t orb[8];
175#define IND_PTR_OFFSET (8*sizeof(uint32_t))
176 struct ind_ptr ind_ptr[SBP_IND_MAX];
177 struct sbp_dev *sdev;
178 int flags; /* XXX should be removed */
179 bus_dmamap_t dmamap;
35 *
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/module.h>
41#include <sys/bus.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>
44#include <machine/bus.h>
45#include <sys/malloc.h>
46#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
47#include <sys/lock.h>
48#include <sys/mutex.h>
49#endif
50
51#if defined(__DragonFly__) || __FreeBSD_version < 500106
52#include <sys/devicestat.h> /* for struct devstat */
53#endif
54
55#ifdef __DragonFly__
56#include <bus/cam/cam.h>
57#include <bus/cam/cam_ccb.h>
58#include <bus/cam/cam_sim.h>
59#include <bus/cam/cam_xpt_sim.h>
60#include <bus/cam/cam_debug.h>
61#include <bus/cam/cam_periph.h>
62#include <bus/cam/scsi/scsi_all.h>
63
64#include <bus/firewire/firewire.h>
65#include <bus/firewire/firewirereg.h>
66#include <bus/firewire/fwdma.h>
67#include <bus/firewire/iec13213.h>
68#include "sbp.h"
69#else
70#include <cam/cam.h>
71#include <cam/cam_ccb.h>
72#include <cam/cam_sim.h>
73#include <cam/cam_xpt_sim.h>
74#include <cam/cam_debug.h>
75#include <cam/cam_periph.h>
76#include <cam/scsi/scsi_all.h>
77
78#include <dev/firewire/firewire.h>
79#include <dev/firewire/firewirereg.h>
80#include <dev/firewire/fwdma.h>
81#include <dev/firewire/iec13213.h>
82#include <dev/firewire/sbp.h>
83#endif
84
85#define ccb_sdev_ptr spriv_ptr0
86#define ccb_sbp_ptr spriv_ptr1
87
88#define SBP_NUM_TARGETS 8 /* MAX 64 */
89/*
90 * Scan_bus doesn't work for more than 8 LUNs
91 * because of CAM_SCSI2_MAXLUN in cam_xpt.c
92 */
93#define SBP_NUM_LUNS 64
94#define SBP_MAXPHYS MIN(MAXPHYS, (512*1024) /* 512KB */)
95#define SBP_DMA_SIZE PAGE_SIZE
96#define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
97#define SBP_QUEUE_LEN ((SBP_DMA_SIZE - SBP_LOGIN_SIZE) / sizeof(struct sbp_ocb))
98#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
99
100/*
101 * STATUS FIFO addressing
102 * bit
103 * -----------------------
104 * 0- 1( 2): 0 (alignment)
105 * 2- 7( 6): target
106 * 8-15( 8): lun
107 * 16-31( 8): reserved
108 * 32-47(16): SBP_BIND_HI
109 * 48-64(16): bus_id, node_id
110 */
111#define SBP_BIND_HI 0x1
112#define SBP_DEV2ADDR(t, l) \
113 (((u_int64_t)SBP_BIND_HI << 32) \
114 | (((l) & 0xff) << 8) \
115 | (((t) & 0x3f) << 2))
116#define SBP_ADDR2TRG(a) (((a) >> 2) & 0x3f)
117#define SBP_ADDR2LUN(a) (((a) >> 8) & 0xff)
118#define SBP_INITIATOR 7
119
120static char *orb_fun_name[] = {
121 ORB_FUN_NAMES
122};
123
124static int debug = 0;
125static int auto_login = 1;
126static int max_speed = -1;
127static int sbp_cold = 1;
128static int ex_login = 1;
129static int login_delay = 1000; /* msec */
130static int scan_delay = 500; /* msec */
131static int use_doorbell = 0;
132static int sbp_tags = 0;
133
134SYSCTL_DECL(_hw_firewire);
135static SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0,
136 "SBP-II Subsystem");
137SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
138 "SBP debug flag");
139SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
140 "SBP perform login automatically");
141SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
142 "SBP transfer max speed");
143SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
144 &ex_login, 0, "SBP enable exclusive login");
145SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
146 &login_delay, 0, "SBP login delay in msec");
147SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
148 &scan_delay, 0, "SBP scan delay in msec");
149SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, use_doorbell, CTLFLAG_RW,
150 &use_doorbell, 0, "SBP use doorbell request");
151SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, tags, CTLFLAG_RW, &sbp_tags, 0,
152 "SBP tagged queuing support");
153
154TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
155TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
156TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
157TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
158TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
159TUNABLE_INT("hw.firewire.sbp.use_doorbell", &use_doorbell);
160TUNABLE_INT("hw.firewire.sbp.tags", &sbp_tags);
161
162#define NEED_RESPONSE 0
163
164#define SBP_SEG_MAX rounddown(0xffff, PAGE_SIZE)
165#ifdef __sparc64__ /* iommu */
166#define SBP_IND_MAX howmany(SBP_MAXPHYS, SBP_SEG_MAX)
167#else
168#define SBP_IND_MAX howmany(SBP_MAXPHYS, PAGE_SIZE)
169#endif
170struct sbp_ocb {
171 STAILQ_ENTRY(sbp_ocb) ocb;
172 union ccb *ccb;
173 bus_addr_t bus_addr;
174 uint32_t orb[8];
175#define IND_PTR_OFFSET (8*sizeof(uint32_t))
176 struct ind_ptr ind_ptr[SBP_IND_MAX];
177 struct sbp_dev *sdev;
178 int flags; /* XXX should be removed */
179 bus_dmamap_t dmamap;
180 struct callout_handle timeout_ch;
180 struct callout timer;
181};
182
183#define OCB_ACT_MGM 0
184#define OCB_ACT_CMD 1
185#define OCB_MATCH(o,s) ((o)->bus_addr == ntohl((s)->orb_lo))
186
187struct sbp_dev{
188#define SBP_DEV_RESET 0 /* accept login */
189#define SBP_DEV_LOGIN 1 /* to login */
190#if 0
191#define SBP_DEV_RECONN 2 /* to reconnect */
192#endif
193#define SBP_DEV_TOATTACH 3 /* to attach */
194#define SBP_DEV_PROBE 4 /* scan lun */
195#define SBP_DEV_ATTACHED 5 /* in operation */
196#define SBP_DEV_DEAD 6 /* unavailable unit */
197#define SBP_DEV_RETRY 7 /* unavailable unit */
198 uint8_t status:4,
199 timeout:4;
200 uint8_t type;
201 uint16_t lun_id;
202 uint16_t freeze;
203#define ORB_LINK_DEAD (1 << 0)
204#define VALID_LUN (1 << 1)
205#define ORB_POINTER_ACTIVE (1 << 2)
206#define ORB_POINTER_NEED (1 << 3)
207#define ORB_DOORBELL_ACTIVE (1 << 4)
208#define ORB_DOORBELL_NEED (1 << 5)
209#define ORB_SHORTAGE (1 << 6)
210 uint16_t flags;
211 struct cam_path *path;
212 struct sbp_target *target;
213 struct fwdma_alloc dma;
214 struct sbp_login_res *login;
215 struct callout login_callout;
216 struct sbp_ocb *ocb;
217 STAILQ_HEAD(, sbp_ocb) ocbs;
218 STAILQ_HEAD(, sbp_ocb) free_ocbs;
219 struct sbp_ocb *last_ocb;
220 char vendor[32];
221 char product[32];
222 char revision[10];
223 char bustgtlun[32];
224};
225
226struct sbp_target {
227 int target_id;
228 int num_lun;
229 struct sbp_dev **luns;
230 struct sbp_softc *sbp;
231 struct fw_device *fwdev;
232 uint32_t mgm_hi, mgm_lo;
233 struct sbp_ocb *mgm_ocb_cur;
234 STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
235 struct callout mgm_ocb_timeout;
236 struct callout scan_callout;
237 STAILQ_HEAD(, fw_xfer) xferlist;
238 int n_xfer;
239};
240
241struct sbp_softc {
242 struct firewire_dev_comm fd;
243 struct cam_sim *sim;
244 struct cam_path *path;
245 struct sbp_target targets[SBP_NUM_TARGETS];
246 struct fw_bind fwb;
247 bus_dma_tag_t dmat;
248 struct timeval last_busreset;
249#define SIMQ_FREEZED 1
250 int flags;
251 struct mtx mtx;
252};
181};
182
183#define OCB_ACT_MGM 0
184#define OCB_ACT_CMD 1
185#define OCB_MATCH(o,s) ((o)->bus_addr == ntohl((s)->orb_lo))
186
187struct sbp_dev{
188#define SBP_DEV_RESET 0 /* accept login */
189#define SBP_DEV_LOGIN 1 /* to login */
190#if 0
191#define SBP_DEV_RECONN 2 /* to reconnect */
192#endif
193#define SBP_DEV_TOATTACH 3 /* to attach */
194#define SBP_DEV_PROBE 4 /* scan lun */
195#define SBP_DEV_ATTACHED 5 /* in operation */
196#define SBP_DEV_DEAD 6 /* unavailable unit */
197#define SBP_DEV_RETRY 7 /* unavailable unit */
198 uint8_t status:4,
199 timeout:4;
200 uint8_t type;
201 uint16_t lun_id;
202 uint16_t freeze;
203#define ORB_LINK_DEAD (1 << 0)
204#define VALID_LUN (1 << 1)
205#define ORB_POINTER_ACTIVE (1 << 2)
206#define ORB_POINTER_NEED (1 << 3)
207#define ORB_DOORBELL_ACTIVE (1 << 4)
208#define ORB_DOORBELL_NEED (1 << 5)
209#define ORB_SHORTAGE (1 << 6)
210 uint16_t flags;
211 struct cam_path *path;
212 struct sbp_target *target;
213 struct fwdma_alloc dma;
214 struct sbp_login_res *login;
215 struct callout login_callout;
216 struct sbp_ocb *ocb;
217 STAILQ_HEAD(, sbp_ocb) ocbs;
218 STAILQ_HEAD(, sbp_ocb) free_ocbs;
219 struct sbp_ocb *last_ocb;
220 char vendor[32];
221 char product[32];
222 char revision[10];
223 char bustgtlun[32];
224};
225
226struct sbp_target {
227 int target_id;
228 int num_lun;
229 struct sbp_dev **luns;
230 struct sbp_softc *sbp;
231 struct fw_device *fwdev;
232 uint32_t mgm_hi, mgm_lo;
233 struct sbp_ocb *mgm_ocb_cur;
234 STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
235 struct callout mgm_ocb_timeout;
236 struct callout scan_callout;
237 STAILQ_HEAD(, fw_xfer) xferlist;
238 int n_xfer;
239};
240
241struct sbp_softc {
242 struct firewire_dev_comm fd;
243 struct cam_sim *sim;
244 struct cam_path *path;
245 struct sbp_target targets[SBP_NUM_TARGETS];
246 struct fw_bind fwb;
247 bus_dma_tag_t dmat;
248 struct timeval last_busreset;
249#define SIMQ_FREEZED 1
250 int flags;
251 struct mtx mtx;
252};
253#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx)
254#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx)
253#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx)
254#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx)
255#define SBP_LOCK_ASSERT(sbp) mtx_assert(&(sbp)->mtx, MA_OWNED)
255
256static void sbp_post_explore (void *);
257static void sbp_recv (struct fw_xfer *);
258static void sbp_mgm_callback (struct fw_xfer *);
259#if 0
260static void sbp_cmd_callback (struct fw_xfer *);
261#endif
262static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
263static void sbp_doorbell(struct sbp_dev *);
264static void sbp_execute_ocb (void *, bus_dma_segment_t *, int, int);
265static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
266static void sbp_abort_ocb (struct sbp_ocb *, int);
267static void sbp_abort_all_ocbs (struct sbp_dev *, int);
256
257static void sbp_post_explore (void *);
258static void sbp_recv (struct fw_xfer *);
259static void sbp_mgm_callback (struct fw_xfer *);
260#if 0
261static void sbp_cmd_callback (struct fw_xfer *);
262#endif
263static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
264static void sbp_doorbell(struct sbp_dev *);
265static void sbp_execute_ocb (void *, bus_dma_segment_t *, int, int);
266static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
267static void sbp_abort_ocb (struct sbp_ocb *, int);
268static void sbp_abort_all_ocbs (struct sbp_dev *, int);
268static struct fw_xfer * sbp_write_cmd_locked (struct sbp_dev *, int, int);
269static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
270static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
271static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
272static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
273static void sbp_cam_detach_sdev(struct sbp_dev *);
274static void sbp_free_sdev(struct sbp_dev *);
275static void sbp_cam_detach_target (struct sbp_target *);
276static void sbp_free_target (struct sbp_target *);
277static void sbp_mgm_timeout (void *arg);
278static void sbp_timeout (void *arg);
279static void sbp_mgm_orb (struct sbp_dev *, int, struct sbp_ocb *);
280
281static MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
282
283/* cam related functions */
284static void sbp_action(struct cam_sim *sim, union ccb *ccb);
285static void sbp_poll(struct cam_sim *sim);
286static void sbp_cam_scan_lun(struct cam_periph *, union ccb *);
287static void sbp_cam_scan_target(void *arg);
288
289static char *orb_status0[] = {
290 /* 0 */ "No additional information to report",
291 /* 1 */ "Request type not supported",
292 /* 2 */ "Speed not supported",
293 /* 3 */ "Page size not supported",
294 /* 4 */ "Access denied",
295 /* 5 */ "Logical unit not supported",
296 /* 6 */ "Maximum payload too small",
297 /* 7 */ "Reserved for future standardization",
298 /* 8 */ "Resources unavailable",
299 /* 9 */ "Function rejected",
300 /* A */ "Login ID not recognized",
301 /* B */ "Dummy ORB completed",
302 /* C */ "Request aborted",
303 /* FF */ "Unspecified error"
304#define MAX_ORB_STATUS0 0xd
305};
306
307static char *orb_status1_object[] = {
308 /* 0 */ "Operation request block (ORB)",
309 /* 1 */ "Data buffer",
310 /* 2 */ "Page table",
311 /* 3 */ "Unable to specify"
312};
313
314static char *orb_status1_serial_bus_error[] = {
315 /* 0 */ "Missing acknowledge",
316 /* 1 */ "Reserved; not to be used",
317 /* 2 */ "Time-out error",
318 /* 3 */ "Reserved; not to be used",
319 /* 4 */ "Busy retry limit exceeded(X)",
320 /* 5 */ "Busy retry limit exceeded(A)",
321 /* 6 */ "Busy retry limit exceeded(B)",
322 /* 7 */ "Reserved for future standardization",
323 /* 8 */ "Reserved for future standardization",
324 /* 9 */ "Reserved for future standardization",
325 /* A */ "Reserved for future standardization",
326 /* B */ "Tardy retry limit exceeded",
327 /* C */ "Conflict error",
328 /* D */ "Data error",
329 /* E */ "Type error",
330 /* F */ "Address error"
331};
332
333static void
334sbp_identify(driver_t *driver, device_t parent)
335{
336SBP_DEBUG(0)
337 printf("sbp_identify\n");
338END_DEBUG
339
269static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
270static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
271static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
272static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
273static void sbp_cam_detach_sdev(struct sbp_dev *);
274static void sbp_free_sdev(struct sbp_dev *);
275static void sbp_cam_detach_target (struct sbp_target *);
276static void sbp_free_target (struct sbp_target *);
277static void sbp_mgm_timeout (void *arg);
278static void sbp_timeout (void *arg);
279static void sbp_mgm_orb (struct sbp_dev *, int, struct sbp_ocb *);
280
281static MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
282
283/* cam related functions */
284static void sbp_action(struct cam_sim *sim, union ccb *ccb);
285static void sbp_poll(struct cam_sim *sim);
286static void sbp_cam_scan_lun(struct cam_periph *, union ccb *);
287static void sbp_cam_scan_target(void *arg);
288
289static char *orb_status0[] = {
290 /* 0 */ "No additional information to report",
291 /* 1 */ "Request type not supported",
292 /* 2 */ "Speed not supported",
293 /* 3 */ "Page size not supported",
294 /* 4 */ "Access denied",
295 /* 5 */ "Logical unit not supported",
296 /* 6 */ "Maximum payload too small",
297 /* 7 */ "Reserved for future standardization",
298 /* 8 */ "Resources unavailable",
299 /* 9 */ "Function rejected",
300 /* A */ "Login ID not recognized",
301 /* B */ "Dummy ORB completed",
302 /* C */ "Request aborted",
303 /* FF */ "Unspecified error"
304#define MAX_ORB_STATUS0 0xd
305};
306
307static char *orb_status1_object[] = {
308 /* 0 */ "Operation request block (ORB)",
309 /* 1 */ "Data buffer",
310 /* 2 */ "Page table",
311 /* 3 */ "Unable to specify"
312};
313
314static char *orb_status1_serial_bus_error[] = {
315 /* 0 */ "Missing acknowledge",
316 /* 1 */ "Reserved; not to be used",
317 /* 2 */ "Time-out error",
318 /* 3 */ "Reserved; not to be used",
319 /* 4 */ "Busy retry limit exceeded(X)",
320 /* 5 */ "Busy retry limit exceeded(A)",
321 /* 6 */ "Busy retry limit exceeded(B)",
322 /* 7 */ "Reserved for future standardization",
323 /* 8 */ "Reserved for future standardization",
324 /* 9 */ "Reserved for future standardization",
325 /* A */ "Reserved for future standardization",
326 /* B */ "Tardy retry limit exceeded",
327 /* C */ "Conflict error",
328 /* D */ "Data error",
329 /* E */ "Type error",
330 /* F */ "Address error"
331};
332
333static void
334sbp_identify(driver_t *driver, device_t parent)
335{
336SBP_DEBUG(0)
337 printf("sbp_identify\n");
338END_DEBUG
339
340 BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
340 if (device_find_child(parent, "sbp", -1) == NULL)
341 BUS_ADD_CHILD(parent, 0, "sbp", -1);
341}
342
343/*
344 * sbp_probe()
345 */
346static int
347sbp_probe(device_t dev)
348{
342}
343
344/*
345 * sbp_probe()
346 */
347static int
348sbp_probe(device_t dev)
349{
349 device_t pa;
350
351SBP_DEBUG(0)
352 printf("sbp_probe\n");
353END_DEBUG
354
350
351SBP_DEBUG(0)
352 printf("sbp_probe\n");
353END_DEBUG
354
355 pa = device_get_parent(dev);
356 if(device_get_unit(dev) != device_get_unit(pa)){
357 return(ENXIO);
358 }
359
360 device_set_desc(dev, "SBP-2/SCSI over FireWire");
361
362#if 0
363 if (bootverbose)
364 debug = bootverbose;
365#endif
366
367 return (0);
368}
369
370/*
371 * Display device characteristics on the console
372 */
373static void
374sbp_show_sdev_info(struct sbp_dev *sdev)
375{
376 struct fw_device *fwdev;
377
378 fwdev = sdev->target->fwdev;
379 device_printf(sdev->target->sbp->fd.dev,
380 "%s: %s: ordered:%d type:%d EUI:%08x%08x node:%d "
381 "speed:%d maxrec:%d\n",
382 __func__,
383 sdev->bustgtlun,
384 (sdev->type & 0x40) >> 6,
385 (sdev->type & 0x1f),
386 fwdev->eui.hi,
387 fwdev->eui.lo,
388 fwdev->dst,
389 fwdev->speed,
390 fwdev->maxrec);
391
392 device_printf(sdev->target->sbp->fd.dev,
393 "%s: %s '%s' '%s' '%s'\n",
394 __func__,
395 sdev->bustgtlun,
396 sdev->vendor,
397 sdev->product,
398 sdev->revision);
399}
400
401static struct {
402 int bus;
403 int target;
404 struct fw_eui64 eui;
405} wired[] = {
406 /* Bus Target EUI64 */
407#if 0
408 {0, 2, {0x00018ea0, 0x01fd0154}}, /* Logitec HDD */
409 {0, 0, {0x00018ea6, 0x00100682}}, /* Logitec DVD */
410 {0, 1, {0x00d03200, 0xa412006a}}, /* Yano HDD */
411#endif
412 {-1, -1, {0,0}}
413};
414
415static int
416sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev)
417{
418 int bus, i, target=-1;
419 char w[SBP_NUM_TARGETS];
420
421 bzero(w, sizeof(w));
422 bus = device_get_unit(sbp->fd.dev);
423
424 /* XXX wired-down configuration should be gotten from
425 tunable or device hint */
426 for (i = 0; wired[i].bus >= 0; i ++) {
427 if (wired[i].bus == bus) {
428 w[wired[i].target] = 1;
429 if (wired[i].eui.hi == fwdev->eui.hi &&
430 wired[i].eui.lo == fwdev->eui.lo)
431 target = wired[i].target;
432 }
433 }
434 if (target >= 0) {
435 if(target < SBP_NUM_TARGETS &&
436 sbp->targets[target].fwdev == NULL)
437 return(target);
438 device_printf(sbp->fd.dev,
439 "target %d is not free for %08x:%08x\n",
440 target, fwdev->eui.hi, fwdev->eui.lo);
441 target = -1;
442 }
443 /* non-wired target */
444 for (i = 0; i < SBP_NUM_TARGETS; i ++)
445 if (sbp->targets[i].fwdev == NULL && w[i] == 0) {
446 target = i;
447 break;
448 }
449
450 return target;
451}
452
453static void
454sbp_alloc_lun(struct sbp_target *target)
455{
456 struct crom_context cc;
457 struct csrreg *reg;
458 struct sbp_dev *sdev, **newluns;
459 struct sbp_softc *sbp;
460 int maxlun, lun, i;
461
462 sbp = target->sbp;
355 device_set_desc(dev, "SBP-2/SCSI over FireWire");
356
357#if 0
358 if (bootverbose)
359 debug = bootverbose;
360#endif
361
362 return (0);
363}
364
365/*
366 * Display device characteristics on the console
367 */
368static void
369sbp_show_sdev_info(struct sbp_dev *sdev)
370{
371 struct fw_device *fwdev;
372
373 fwdev = sdev->target->fwdev;
374 device_printf(sdev->target->sbp->fd.dev,
375 "%s: %s: ordered:%d type:%d EUI:%08x%08x node:%d "
376 "speed:%d maxrec:%d\n",
377 __func__,
378 sdev->bustgtlun,
379 (sdev->type & 0x40) >> 6,
380 (sdev->type & 0x1f),
381 fwdev->eui.hi,
382 fwdev->eui.lo,
383 fwdev->dst,
384 fwdev->speed,
385 fwdev->maxrec);
386
387 device_printf(sdev->target->sbp->fd.dev,
388 "%s: %s '%s' '%s' '%s'\n",
389 __func__,
390 sdev->bustgtlun,
391 sdev->vendor,
392 sdev->product,
393 sdev->revision);
394}
395
396static struct {
397 int bus;
398 int target;
399 struct fw_eui64 eui;
400} wired[] = {
401 /* Bus Target EUI64 */
402#if 0
403 {0, 2, {0x00018ea0, 0x01fd0154}}, /* Logitec HDD */
404 {0, 0, {0x00018ea6, 0x00100682}}, /* Logitec DVD */
405 {0, 1, {0x00d03200, 0xa412006a}}, /* Yano HDD */
406#endif
407 {-1, -1, {0,0}}
408};
409
410static int
411sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev)
412{
413 int bus, i, target=-1;
414 char w[SBP_NUM_TARGETS];
415
416 bzero(w, sizeof(w));
417 bus = device_get_unit(sbp->fd.dev);
418
419 /* XXX wired-down configuration should be gotten from
420 tunable or device hint */
421 for (i = 0; wired[i].bus >= 0; i ++) {
422 if (wired[i].bus == bus) {
423 w[wired[i].target] = 1;
424 if (wired[i].eui.hi == fwdev->eui.hi &&
425 wired[i].eui.lo == fwdev->eui.lo)
426 target = wired[i].target;
427 }
428 }
429 if (target >= 0) {
430 if(target < SBP_NUM_TARGETS &&
431 sbp->targets[target].fwdev == NULL)
432 return(target);
433 device_printf(sbp->fd.dev,
434 "target %d is not free for %08x:%08x\n",
435 target, fwdev->eui.hi, fwdev->eui.lo);
436 target = -1;
437 }
438 /* non-wired target */
439 for (i = 0; i < SBP_NUM_TARGETS; i ++)
440 if (sbp->targets[i].fwdev == NULL && w[i] == 0) {
441 target = i;
442 break;
443 }
444
445 return target;
446}
447
448static void
449sbp_alloc_lun(struct sbp_target *target)
450{
451 struct crom_context cc;
452 struct csrreg *reg;
453 struct sbp_dev *sdev, **newluns;
454 struct sbp_softc *sbp;
455 int maxlun, lun, i;
456
457 sbp = target->sbp;
458 SBP_LOCK_ASSERT(sbp);
463 crom_init_context(&cc, target->fwdev->csrrom);
464 /* XXX shoud parse appropriate unit directories only */
465 maxlun = -1;
466 while (cc.depth >= 0) {
467 reg = crom_search_key(&cc, CROM_LUN);
468 if (reg == NULL)
469 break;
470 lun = reg->val & 0xffff;
471SBP_DEBUG(0)
472 printf("target %d lun %d found\n", target->target_id, lun);
473END_DEBUG
474 if (maxlun < lun)
475 maxlun = lun;
476 crom_next(&cc);
477 }
478 if (maxlun < 0)
459 crom_init_context(&cc, target->fwdev->csrrom);
460 /* XXX shoud parse appropriate unit directories only */
461 maxlun = -1;
462 while (cc.depth >= 0) {
463 reg = crom_search_key(&cc, CROM_LUN);
464 if (reg == NULL)
465 break;
466 lun = reg->val & 0xffff;
467SBP_DEBUG(0)
468 printf("target %d lun %d found\n", target->target_id, lun);
469END_DEBUG
470 if (maxlun < lun)
471 maxlun = lun;
472 crom_next(&cc);
473 }
474 if (maxlun < 0)
479 printf("%s:%d no LUN found\n",
480 device_get_nameunit(target->sbp->fd.dev),
475 device_printf(target->sbp->fd.dev, "%d no LUN found\n",
481 target->target_id);
482
483 maxlun ++;
484 if (maxlun >= SBP_NUM_LUNS)
485 maxlun = SBP_NUM_LUNS;
486
487 /* Invalidiate stale devices */
488 for (lun = 0; lun < target->num_lun; lun ++) {
489 sdev = target->luns[lun];
490 if (sdev == NULL)
491 continue;
492 sdev->flags &= ~VALID_LUN;
493 if (lun >= maxlun) {
494 /* lost device */
495 sbp_cam_detach_sdev(sdev);
496 sbp_free_sdev(sdev);
497 target->luns[lun] = NULL;
498 }
499 }
500
501 /* Reallocate */
502 if (maxlun != target->num_lun) {
503 newluns = (struct sbp_dev **) realloc(target->luns,
504 sizeof(struct sbp_dev *) * maxlun,
505 M_SBP, M_NOWAIT | M_ZERO);
506
507 if (newluns == NULL) {
508 printf("%s: realloc failed\n", __func__);
509 newluns = target->luns;
510 maxlun = target->num_lun;
511 }
512
513 /*
514 * We must zero the extended region for the case
515 * realloc() doesn't allocate new buffer.
516 */
517 if (maxlun > target->num_lun)
518 bzero(&newluns[target->num_lun],
519 sizeof(struct sbp_dev *) *
520 (maxlun - target->num_lun));
521
522 target->luns = newluns;
523 target->num_lun = maxlun;
524 }
525
526 crom_init_context(&cc, target->fwdev->csrrom);
527 while (cc.depth >= 0) {
528 int new = 0;
529
530 reg = crom_search_key(&cc, CROM_LUN);
531 if (reg == NULL)
532 break;
533 lun = reg->val & 0xffff;
534 if (lun >= SBP_NUM_LUNS) {
535 printf("too large lun %d\n", lun);
536 goto next;
537 }
538
539 sdev = target->luns[lun];
540 if (sdev == NULL) {
541 sdev = malloc(sizeof(struct sbp_dev),
542 M_SBP, M_NOWAIT | M_ZERO);
543 if (sdev == NULL) {
544 printf("%s: malloc failed\n", __func__);
545 goto next;
546 }
547 target->luns[lun] = sdev;
548 sdev->lun_id = lun;
549 sdev->target = target;
550 STAILQ_INIT(&sdev->ocbs);
476 target->target_id);
477
478 maxlun ++;
479 if (maxlun >= SBP_NUM_LUNS)
480 maxlun = SBP_NUM_LUNS;
481
482 /* Invalidiate stale devices */
483 for (lun = 0; lun < target->num_lun; lun ++) {
484 sdev = target->luns[lun];
485 if (sdev == NULL)
486 continue;
487 sdev->flags &= ~VALID_LUN;
488 if (lun >= maxlun) {
489 /* lost device */
490 sbp_cam_detach_sdev(sdev);
491 sbp_free_sdev(sdev);
492 target->luns[lun] = NULL;
493 }
494 }
495
496 /* Reallocate */
497 if (maxlun != target->num_lun) {
498 newluns = (struct sbp_dev **) realloc(target->luns,
499 sizeof(struct sbp_dev *) * maxlun,
500 M_SBP, M_NOWAIT | M_ZERO);
501
502 if (newluns == NULL) {
503 printf("%s: realloc failed\n", __func__);
504 newluns = target->luns;
505 maxlun = target->num_lun;
506 }
507
508 /*
509 * We must zero the extended region for the case
510 * realloc() doesn't allocate new buffer.
511 */
512 if (maxlun > target->num_lun)
513 bzero(&newluns[target->num_lun],
514 sizeof(struct sbp_dev *) *
515 (maxlun - target->num_lun));
516
517 target->luns = newluns;
518 target->num_lun = maxlun;
519 }
520
521 crom_init_context(&cc, target->fwdev->csrrom);
522 while (cc.depth >= 0) {
523 int new = 0;
524
525 reg = crom_search_key(&cc, CROM_LUN);
526 if (reg == NULL)
527 break;
528 lun = reg->val & 0xffff;
529 if (lun >= SBP_NUM_LUNS) {
530 printf("too large lun %d\n", lun);
531 goto next;
532 }
533
534 sdev = target->luns[lun];
535 if (sdev == NULL) {
536 sdev = malloc(sizeof(struct sbp_dev),
537 M_SBP, M_NOWAIT | M_ZERO);
538 if (sdev == NULL) {
539 printf("%s: malloc failed\n", __func__);
540 goto next;
541 }
542 target->luns[lun] = sdev;
543 sdev->lun_id = lun;
544 sdev->target = target;
545 STAILQ_INIT(&sdev->ocbs);
551 CALLOUT_INIT(&sdev->login_callout);
546 callout_init_mtx(&sdev->login_callout, &sbp->mtx, 0);
552 sdev->status = SBP_DEV_RESET;
553 new = 1;
554 snprintf(sdev->bustgtlun, 32, "%s:%d:%d",
555 device_get_nameunit(sdev->target->sbp->fd.dev),
556 sdev->target->target_id,
557 sdev->lun_id);
558 }
559 sdev->flags |= VALID_LUN;
560 sdev->type = (reg->val & 0xff0000) >> 16;
561
562 if (new == 0)
563 goto next;
564
565 fwdma_malloc(sbp->fd.fc,
566 /* alignment */ sizeof(uint32_t),
567 SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT |
568 BUS_DMA_COHERENT);
569 if (sdev->dma.v_addr == NULL) {
570 printf("%s: dma space allocation failed\n",
571 __func__);
572 free(sdev, M_SBP);
573 target->luns[lun] = NULL;
574 goto next;
575 }
576 sdev->login = (struct sbp_login_res *) sdev->dma.v_addr;
577 sdev->ocb = (struct sbp_ocb *)
578 ((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE);
579 bzero((char *)sdev->ocb,
580 sizeof (struct sbp_ocb) * SBP_QUEUE_LEN);
581
582 STAILQ_INIT(&sdev->free_ocbs);
583 for (i = 0; i < SBP_QUEUE_LEN; i++) {
584 struct sbp_ocb *ocb;
585 ocb = &sdev->ocb[i];
586 ocb->bus_addr = sdev->dma.bus_addr
587 + SBP_LOGIN_SIZE
588 + sizeof(struct sbp_ocb) * i
589 + offsetof(struct sbp_ocb, orb[0]);
590 if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
591 printf("sbp_attach: cannot create dmamap\n");
592 /* XXX */
593 goto next;
594 }
547 sdev->status = SBP_DEV_RESET;
548 new = 1;
549 snprintf(sdev->bustgtlun, 32, "%s:%d:%d",
550 device_get_nameunit(sdev->target->sbp->fd.dev),
551 sdev->target->target_id,
552 sdev->lun_id);
553 }
554 sdev->flags |= VALID_LUN;
555 sdev->type = (reg->val & 0xff0000) >> 16;
556
557 if (new == 0)
558 goto next;
559
560 fwdma_malloc(sbp->fd.fc,
561 /* alignment */ sizeof(uint32_t),
562 SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT |
563 BUS_DMA_COHERENT);
564 if (sdev->dma.v_addr == NULL) {
565 printf("%s: dma space allocation failed\n",
566 __func__);
567 free(sdev, M_SBP);
568 target->luns[lun] = NULL;
569 goto next;
570 }
571 sdev->login = (struct sbp_login_res *) sdev->dma.v_addr;
572 sdev->ocb = (struct sbp_ocb *)
573 ((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE);
574 bzero((char *)sdev->ocb,
575 sizeof (struct sbp_ocb) * SBP_QUEUE_LEN);
576
577 STAILQ_INIT(&sdev->free_ocbs);
578 for (i = 0; i < SBP_QUEUE_LEN; i++) {
579 struct sbp_ocb *ocb;
580 ocb = &sdev->ocb[i];
581 ocb->bus_addr = sdev->dma.bus_addr
582 + SBP_LOGIN_SIZE
583 + sizeof(struct sbp_ocb) * i
584 + offsetof(struct sbp_ocb, orb[0]);
585 if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
586 printf("sbp_attach: cannot create dmamap\n");
587 /* XXX */
588 goto next;
589 }
595 callout_handle_init(&ocb->timeout_ch);
590 callout_init_mtx(&ocb->timer, &sbp->mtx, 0);
596 sbp_free_ocb(sdev, ocb);
597 }
598next:
599 crom_next(&cc);
600 }
601
602 for (lun = 0; lun < target->num_lun; lun ++) {
603 sdev = target->luns[lun];
604 if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) {
605 sbp_cam_detach_sdev(sdev);
606 sbp_free_sdev(sdev);
607 target->luns[lun] = NULL;
608 }
609 }
610}
611
612static struct sbp_target *
613sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
614{
615 int i;
616 struct sbp_target *target;
617 struct crom_context cc;
618 struct csrreg *reg;
619
620SBP_DEBUG(1)
621 printf("sbp_alloc_target\n");
622END_DEBUG
623 i = sbp_new_target(sbp, fwdev);
624 if (i < 0) {
625 device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n");
626 return NULL;
627 }
628 /* new target */
629 target = &sbp->targets[i];
630 target->sbp = sbp;
631 target->fwdev = fwdev;
632 target->target_id = i;
633 /* XXX we may want to reload mgm port after each bus reset */
634 /* XXX there might be multiple management agents */
635 crom_init_context(&cc, target->fwdev->csrrom);
636 reg = crom_search_key(&cc, CROM_MGM);
637 if (reg == NULL || reg->val == 0) {
638 printf("NULL management address\n");
639 target->fwdev = NULL;
640 return NULL;
641 }
642 target->mgm_hi = 0xffff;
643 target->mgm_lo = 0xf0000000 | (reg->val << 2);
644 target->mgm_ocb_cur = NULL;
645SBP_DEBUG(1)
646 printf("target:%d mgm_port: %x\n", i, target->mgm_lo);
647END_DEBUG
648 STAILQ_INIT(&target->xferlist);
649 target->n_xfer = 0;
650 STAILQ_INIT(&target->mgm_ocb_queue);
591 sbp_free_ocb(sdev, ocb);
592 }
593next:
594 crom_next(&cc);
595 }
596
597 for (lun = 0; lun < target->num_lun; lun ++) {
598 sdev = target->luns[lun];
599 if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) {
600 sbp_cam_detach_sdev(sdev);
601 sbp_free_sdev(sdev);
602 target->luns[lun] = NULL;
603 }
604 }
605}
606
607static struct sbp_target *
608sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
609{
610 int i;
611 struct sbp_target *target;
612 struct crom_context cc;
613 struct csrreg *reg;
614
615SBP_DEBUG(1)
616 printf("sbp_alloc_target\n");
617END_DEBUG
618 i = sbp_new_target(sbp, fwdev);
619 if (i < 0) {
620 device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n");
621 return NULL;
622 }
623 /* new target */
624 target = &sbp->targets[i];
625 target->sbp = sbp;
626 target->fwdev = fwdev;
627 target->target_id = i;
628 /* XXX we may want to reload mgm port after each bus reset */
629 /* XXX there might be multiple management agents */
630 crom_init_context(&cc, target->fwdev->csrrom);
631 reg = crom_search_key(&cc, CROM_MGM);
632 if (reg == NULL || reg->val == 0) {
633 printf("NULL management address\n");
634 target->fwdev = NULL;
635 return NULL;
636 }
637 target->mgm_hi = 0xffff;
638 target->mgm_lo = 0xf0000000 | (reg->val << 2);
639 target->mgm_ocb_cur = NULL;
640SBP_DEBUG(1)
641 printf("target:%d mgm_port: %x\n", i, target->mgm_lo);
642END_DEBUG
643 STAILQ_INIT(&target->xferlist);
644 target->n_xfer = 0;
645 STAILQ_INIT(&target->mgm_ocb_queue);
651 CALLOUT_INIT(&target->mgm_ocb_timeout);
652 CALLOUT_INIT(&target->scan_callout);
646 callout_init_mtx(&target->mgm_ocb_timeout, &sbp->mtx, 0);
647 callout_init_mtx(&target->scan_callout, &sbp->mtx, 0);
653
654 target->luns = NULL;
655 target->num_lun = 0;
656 return target;
657}
658
659static void
660sbp_probe_lun(struct sbp_dev *sdev)
661{
662 struct fw_device *fwdev;
663 struct crom_context c, *cc = &c;
664 struct csrreg *reg;
665
666 bzero(sdev->vendor, sizeof(sdev->vendor));
667 bzero(sdev->product, sizeof(sdev->product));
668
669 fwdev = sdev->target->fwdev;
670 crom_init_context(cc, fwdev->csrrom);
671 /* get vendor string */
672 crom_search_key(cc, CSRKEY_VENDOR);
673 crom_next(cc);
674 crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor));
675 /* skip to the unit directory for SBP-2 */
676 while ((reg = crom_search_key(cc, CSRKEY_VER)) != NULL) {
677 if (reg->val == CSRVAL_T10SBP2)
678 break;
679 crom_next(cc);
680 }
681 /* get firmware revision */
682 reg = crom_search_key(cc, CSRKEY_FIRM_VER);
683 if (reg != NULL)
684 snprintf(sdev->revision, sizeof(sdev->revision),
685 "%06x", reg->val);
686 /* get product string */
687 crom_search_key(cc, CSRKEY_MODEL);
688 crom_next(cc);
689 crom_parse_text(cc, sdev->product, sizeof(sdev->product));
690}
691
692static void
693sbp_login_callout(void *arg)
694{
695 struct sbp_dev *sdev = (struct sbp_dev *)arg;
648
649 target->luns = NULL;
650 target->num_lun = 0;
651 return target;
652}
653
654static void
655sbp_probe_lun(struct sbp_dev *sdev)
656{
657 struct fw_device *fwdev;
658 struct crom_context c, *cc = &c;
659 struct csrreg *reg;
660
661 bzero(sdev->vendor, sizeof(sdev->vendor));
662 bzero(sdev->product, sizeof(sdev->product));
663
664 fwdev = sdev->target->fwdev;
665 crom_init_context(cc, fwdev->csrrom);
666 /* get vendor string */
667 crom_search_key(cc, CSRKEY_VENDOR);
668 crom_next(cc);
669 crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor));
670 /* skip to the unit directory for SBP-2 */
671 while ((reg = crom_search_key(cc, CSRKEY_VER)) != NULL) {
672 if (reg->val == CSRVAL_T10SBP2)
673 break;
674 crom_next(cc);
675 }
676 /* get firmware revision */
677 reg = crom_search_key(cc, CSRKEY_FIRM_VER);
678 if (reg != NULL)
679 snprintf(sdev->revision, sizeof(sdev->revision),
680 "%06x", reg->val);
681 /* get product string */
682 crom_search_key(cc, CSRKEY_MODEL);
683 crom_next(cc);
684 crom_parse_text(cc, sdev->product, sizeof(sdev->product));
685}
686
687static void
688sbp_login_callout(void *arg)
689{
690 struct sbp_dev *sdev = (struct sbp_dev *)arg;
691 SBP_LOCK_ASSERT(sdev->target->sbp);
696 sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
697}
698
699static void
700sbp_login(struct sbp_dev *sdev)
701{
702 struct timeval delta;
703 struct timeval t;
704 int ticks = 0;
705
706 microtime(&delta);
707 timevalsub(&delta, &sdev->target->sbp->last_busreset);
708 t.tv_sec = login_delay / 1000;
709 t.tv_usec = (login_delay % 1000) * 1000;
710 timevalsub(&t, &delta);
711 if (t.tv_sec >= 0 && t.tv_usec > 0)
712 ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
713SBP_DEBUG(0)
714 printf("%s: sec = %jd usec = %ld ticks = %d\n", __func__,
715 (intmax_t)t.tv_sec, t.tv_usec, ticks);
716END_DEBUG
717 callout_reset(&sdev->login_callout, ticks,
718 sbp_login_callout, (void *)(sdev));
719}
720
721#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
722 && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
723
724static void
725sbp_probe_target(void *arg)
726{
727 struct sbp_target *target = (struct sbp_target *)arg;
728 struct sbp_softc *sbp = target->sbp;
729 struct sbp_dev *sdev;
730 int i, alive;
731
732 alive = SBP_FWDEV_ALIVE(target->fwdev);
733SBP_DEBUG(1)
734 device_printf(sbp->fd.dev, "%s %d%salive\n",
735 __func__, target->target_id,
736 (!alive) ? " not " : "");
737END_DEBUG
738
739 sbp = target->sbp;
692 sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
693}
694
695static void
696sbp_login(struct sbp_dev *sdev)
697{
698 struct timeval delta;
699 struct timeval t;
700 int ticks = 0;
701
702 microtime(&delta);
703 timevalsub(&delta, &sdev->target->sbp->last_busreset);
704 t.tv_sec = login_delay / 1000;
705 t.tv_usec = (login_delay % 1000) * 1000;
706 timevalsub(&t, &delta);
707 if (t.tv_sec >= 0 && t.tv_usec > 0)
708 ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
709SBP_DEBUG(0)
710 printf("%s: sec = %jd usec = %ld ticks = %d\n", __func__,
711 (intmax_t)t.tv_sec, t.tv_usec, ticks);
712END_DEBUG
713 callout_reset(&sdev->login_callout, ticks,
714 sbp_login_callout, (void *)(sdev));
715}
716
717#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
718 && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
719
720static void
721sbp_probe_target(void *arg)
722{
723 struct sbp_target *target = (struct sbp_target *)arg;
724 struct sbp_softc *sbp = target->sbp;
725 struct sbp_dev *sdev;
726 int i, alive;
727
728 alive = SBP_FWDEV_ALIVE(target->fwdev);
729SBP_DEBUG(1)
730 device_printf(sbp->fd.dev, "%s %d%salive\n",
731 __func__, target->target_id,
732 (!alive) ? " not " : "");
733END_DEBUG
734
735 sbp = target->sbp;
736 SBP_LOCK_ASSERT(sbp);
740 sbp_alloc_lun(target);
741
742 /* XXX untimeout mgm_ocb and dequeue */
743 for (i=0; i < target->num_lun; i++) {
744 sdev = target->luns[i];
745 if (sdev == NULL)
746 continue;
747 if (alive && (sdev->status != SBP_DEV_DEAD)) {
748 if (sdev->path != NULL) {
737 sbp_alloc_lun(target);
738
739 /* XXX untimeout mgm_ocb and dequeue */
740 for (i=0; i < target->num_lun; i++) {
741 sdev = target->luns[i];
742 if (sdev == NULL)
743 continue;
744 if (alive && (sdev->status != SBP_DEV_DEAD)) {
745 if (sdev->path != NULL) {
749 SBP_LOCK(sbp);
750 xpt_freeze_devq(sdev->path, 1);
751 sdev->freeze ++;
746 xpt_freeze_devq(sdev->path, 1);
747 sdev->freeze ++;
752 SBP_UNLOCK(sbp);
753 }
754 sbp_probe_lun(sdev);
755 sbp_show_sdev_info(sdev);
756
757 sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
758 switch (sdev->status) {
759 case SBP_DEV_RESET:
760 /* new or revived target */
761 if (auto_login)
762 sbp_login(sdev);
763 break;
764 case SBP_DEV_TOATTACH:
765 case SBP_DEV_PROBE:
766 case SBP_DEV_ATTACHED:
767 case SBP_DEV_RETRY:
768 default:
769 sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
770 break;
771 }
772 } else {
773 switch (sdev->status) {
774 case SBP_DEV_ATTACHED:
775SBP_DEBUG(0)
776 /* the device has gone */
777 device_printf(sbp->fd.dev, "%s: lost target\n",
778 __func__);
779END_DEBUG
780 if (sdev->path) {
748 }
749 sbp_probe_lun(sdev);
750 sbp_show_sdev_info(sdev);
751
752 sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
753 switch (sdev->status) {
754 case SBP_DEV_RESET:
755 /* new or revived target */
756 if (auto_login)
757 sbp_login(sdev);
758 break;
759 case SBP_DEV_TOATTACH:
760 case SBP_DEV_PROBE:
761 case SBP_DEV_ATTACHED:
762 case SBP_DEV_RETRY:
763 default:
764 sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
765 break;
766 }
767 } else {
768 switch (sdev->status) {
769 case SBP_DEV_ATTACHED:
770SBP_DEBUG(0)
771 /* the device has gone */
772 device_printf(sbp->fd.dev, "%s: lost target\n",
773 __func__);
774END_DEBUG
775 if (sdev->path) {
781 SBP_LOCK(sbp);
782 xpt_freeze_devq(sdev->path, 1);
783 sdev->freeze ++;
776 xpt_freeze_devq(sdev->path, 1);
777 sdev->freeze ++;
784 SBP_UNLOCK(sbp);
785 }
786 sdev->status = SBP_DEV_RETRY;
787 sbp_cam_detach_sdev(sdev);
788 sbp_free_sdev(sdev);
789 target->luns[i] = NULL;
790 break;
791 case SBP_DEV_PROBE:
792 case SBP_DEV_TOATTACH:
793 sdev->status = SBP_DEV_RESET;
794 break;
795 case SBP_DEV_RETRY:
796 case SBP_DEV_RESET:
797 case SBP_DEV_DEAD:
798 break;
799 }
800 }
801 }
802}
803
804static void
805sbp_post_busreset(void *arg)
806{
807 struct sbp_softc *sbp;
808
809 sbp = (struct sbp_softc *)arg;
810SBP_DEBUG(0)
811 printf("sbp_post_busreset\n");
812END_DEBUG
778 }
779 sdev->status = SBP_DEV_RETRY;
780 sbp_cam_detach_sdev(sdev);
781 sbp_free_sdev(sdev);
782 target->luns[i] = NULL;
783 break;
784 case SBP_DEV_PROBE:
785 case SBP_DEV_TOATTACH:
786 sdev->status = SBP_DEV_RESET;
787 break;
788 case SBP_DEV_RETRY:
789 case SBP_DEV_RESET:
790 case SBP_DEV_DEAD:
791 break;
792 }
793 }
794 }
795}
796
797static void
798sbp_post_busreset(void *arg)
799{
800 struct sbp_softc *sbp;
801
802 sbp = (struct sbp_softc *)arg;
803SBP_DEBUG(0)
804 printf("sbp_post_busreset\n");
805END_DEBUG
806 SBP_LOCK(sbp);
813 if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
807 if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
814 SBP_LOCK(sbp);
815 xpt_freeze_simq(sbp->sim, /*count*/1);
816 sbp->sim->flags |= SIMQ_FREEZED;
808 xpt_freeze_simq(sbp->sim, /*count*/1);
809 sbp->sim->flags |= SIMQ_FREEZED;
817 SBP_UNLOCK(sbp);
818 }
819 microtime(&sbp->last_busreset);
810 }
811 microtime(&sbp->last_busreset);
812 SBP_UNLOCK(sbp);
820}
821
822static void
823sbp_post_explore(void *arg)
824{
825 struct sbp_softc *sbp = (struct sbp_softc *)arg;
826 struct sbp_target *target;
827 struct fw_device *fwdev;
828 int i, alive;
829
830SBP_DEBUG(0)
831 printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
832END_DEBUG
833 /* We need physical access */
834 if (!firewire_phydma_enable)
835 return;
836
837 if (sbp_cold > 0)
838 sbp_cold --;
839
813}
814
815static void
816sbp_post_explore(void *arg)
817{
818 struct sbp_softc *sbp = (struct sbp_softc *)arg;
819 struct sbp_target *target;
820 struct fw_device *fwdev;
821 int i, alive;
822
823SBP_DEBUG(0)
824 printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
825END_DEBUG
826 /* We need physical access */
827 if (!firewire_phydma_enable)
828 return;
829
830 if (sbp_cold > 0)
831 sbp_cold --;
832
833 SBP_LOCK(sbp);
840#if 0
841 /*
842 * XXX don't let CAM the bus rest.
843 * CAM tries to do something with freezed (DEV_RETRY) devices.
844 */
845 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
846#endif
847
848 /* Garbage Collection */
849 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
850 target = &sbp->targets[i];
851 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link)
852 if (target->fwdev == NULL || target->fwdev == fwdev)
853 break;
854 if (fwdev == NULL) {
855 /* device has removed in lower driver */
856 sbp_cam_detach_target(target);
857 sbp_free_target(target);
858 }
859 }
860 /* traverse device list */
861 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) {
862SBP_DEBUG(0)
863 device_printf(sbp->fd.dev,"%s:: EUI:%08x%08x %s attached, state=%d\n",
864 __func__, fwdev->eui.hi, fwdev->eui.lo,
865 (fwdev->status != FWDEVATTACHED) ? "not" : "",
866 fwdev->status);
867END_DEBUG
868 alive = SBP_FWDEV_ALIVE(fwdev);
869 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
870 target = &sbp->targets[i];
871 if(target->fwdev == fwdev ) {
872 /* known target */
873 break;
874 }
875 }
876 if(i == SBP_NUM_TARGETS){
877 if (alive) {
878 /* new target */
879 target = sbp_alloc_target(sbp, fwdev);
880 if (target == NULL)
881 continue;
882 } else {
883 continue;
884 }
885 }
886 sbp_probe_target((void *)target);
887 if (target->num_lun == 0)
888 sbp_free_target(target);
889 }
834#if 0
835 /*
836 * XXX don't let CAM the bus rest.
837 * CAM tries to do something with freezed (DEV_RETRY) devices.
838 */
839 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
840#endif
841
842 /* Garbage Collection */
843 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
844 target = &sbp->targets[i];
845 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link)
846 if (target->fwdev == NULL || target->fwdev == fwdev)
847 break;
848 if (fwdev == NULL) {
849 /* device has removed in lower driver */
850 sbp_cam_detach_target(target);
851 sbp_free_target(target);
852 }
853 }
854 /* traverse device list */
855 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) {
856SBP_DEBUG(0)
857 device_printf(sbp->fd.dev,"%s:: EUI:%08x%08x %s attached, state=%d\n",
858 __func__, fwdev->eui.hi, fwdev->eui.lo,
859 (fwdev->status != FWDEVATTACHED) ? "not" : "",
860 fwdev->status);
861END_DEBUG
862 alive = SBP_FWDEV_ALIVE(fwdev);
863 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
864 target = &sbp->targets[i];
865 if(target->fwdev == fwdev ) {
866 /* known target */
867 break;
868 }
869 }
870 if(i == SBP_NUM_TARGETS){
871 if (alive) {
872 /* new target */
873 target = sbp_alloc_target(sbp, fwdev);
874 if (target == NULL)
875 continue;
876 } else {
877 continue;
878 }
879 }
880 sbp_probe_target((void *)target);
881 if (target->num_lun == 0)
882 sbp_free_target(target);
883 }
890 SBP_LOCK(sbp);
891 xpt_release_simq(sbp->sim, /*run queue*/TRUE);
892 sbp->sim->flags &= ~SIMQ_FREEZED;
893 SBP_UNLOCK(sbp);
894}
895
896#if NEED_RESPONSE
897static void
898sbp_loginres_callback(struct fw_xfer *xfer){
884 xpt_release_simq(sbp->sim, /*run queue*/TRUE);
885 sbp->sim->flags &= ~SIMQ_FREEZED;
886 SBP_UNLOCK(sbp);
887}
888
889#if NEED_RESPONSE
890static void
891sbp_loginres_callback(struct fw_xfer *xfer){
899 int s;
900 struct sbp_dev *sdev;
901 sdev = (struct sbp_dev *)xfer->sc;
902SBP_DEBUG(1)
903 device_printf(sdev->target->sbp->fd.dev,"%s\n", __func__);
904END_DEBUG
905 /* recycle */
892 struct sbp_dev *sdev;
893 sdev = (struct sbp_dev *)xfer->sc;
894SBP_DEBUG(1)
895 device_printf(sdev->target->sbp->fd.dev,"%s\n", __func__);
896END_DEBUG
897 /* recycle */
906 s = splfw();
898 SBP_LOCK(sdev->target->sbp);
907 STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
899 STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
908 splx(s);
900 SBP_UNLOCK(sdev->target->sbp);
909 return;
910}
911#endif
912
913static __inline void
914sbp_xfer_free(struct fw_xfer *xfer)
915{
916 struct sbp_dev *sdev;
901 return;
902}
903#endif
904
905static __inline void
906sbp_xfer_free(struct fw_xfer *xfer)
907{
908 struct sbp_dev *sdev;
917 int s;
918
919 sdev = (struct sbp_dev *)xfer->sc;
920 fw_xfer_unload(xfer);
909
910 sdev = (struct sbp_dev *)xfer->sc;
911 fw_xfer_unload(xfer);
921 s = splfw();
922 SBP_LOCK(sdev->target->sbp);
912 SBP_LOCK_ASSERT(sdev->target->sbp);
923 STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
913 STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
924 SBP_UNLOCK(sdev->target->sbp);
925 splx(s);
926}
927
928static void
929sbp_reset_start_callback(struct fw_xfer *xfer)
930{
931 struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc;
932 struct sbp_target *target = sdev->target;
933 int i;
934
935 if (xfer->resp != 0) {
936 device_printf(sdev->target->sbp->fd.dev,
937 "%s: %s failed: resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
938 }
939
914}
915
916static void
917sbp_reset_start_callback(struct fw_xfer *xfer)
918{
919 struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc;
920 struct sbp_target *target = sdev->target;
921 int i;
922
923 if (xfer->resp != 0) {
924 device_printf(sdev->target->sbp->fd.dev,
925 "%s: %s failed: resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
926 }
927
928 SBP_LOCK(target->sbp);
940 for (i = 0; i < target->num_lun; i++) {
941 tsdev = target->luns[i];
942 if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN)
943 sbp_login(tsdev);
944 }
929 for (i = 0; i < target->num_lun; i++) {
930 tsdev = target->luns[i];
931 if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN)
932 sbp_login(tsdev);
933 }
934 SBP_UNLOCK(target->sbp);
945}
946
947static void
948sbp_reset_start(struct sbp_dev *sdev)
949{
950 struct fw_xfer *xfer;
951 struct fw_pkt *fp;
952
953SBP_DEBUG(0)
954 device_printf(sdev->target->sbp->fd.dev,
955 "%s:%s\n", __func__,sdev->bustgtlun);
956END_DEBUG
957
958 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
959 xfer->hand = sbp_reset_start_callback;
960 fp = &xfer->send.hdr;
961 fp->mode.wreqq.dest_hi = 0xffff;
962 fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START;
963 fp->mode.wreqq.data = htonl(0xf);
964 fw_asyreq(xfer->fc, -1, xfer);
965}
966
967static void
968sbp_mgm_callback(struct fw_xfer *xfer)
969{
970 struct sbp_dev *sdev;
971 int resp;
972
973 sdev = (struct sbp_dev *)xfer->sc;
974
975SBP_DEBUG(1)
976 device_printf(sdev->target->sbp->fd.dev,
977 "%s:%s\n", __func__, sdev->bustgtlun);
978END_DEBUG
979 resp = xfer->resp;
935}
936
937static void
938sbp_reset_start(struct sbp_dev *sdev)
939{
940 struct fw_xfer *xfer;
941 struct fw_pkt *fp;
942
943SBP_DEBUG(0)
944 device_printf(sdev->target->sbp->fd.dev,
945 "%s:%s\n", __func__,sdev->bustgtlun);
946END_DEBUG
947
948 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
949 xfer->hand = sbp_reset_start_callback;
950 fp = &xfer->send.hdr;
951 fp->mode.wreqq.dest_hi = 0xffff;
952 fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START;
953 fp->mode.wreqq.data = htonl(0xf);
954 fw_asyreq(xfer->fc, -1, xfer);
955}
956
957static void
958sbp_mgm_callback(struct fw_xfer *xfer)
959{
960 struct sbp_dev *sdev;
961 int resp;
962
963 sdev = (struct sbp_dev *)xfer->sc;
964
965SBP_DEBUG(1)
966 device_printf(sdev->target->sbp->fd.dev,
967 "%s:%s\n", __func__, sdev->bustgtlun);
968END_DEBUG
969 resp = xfer->resp;
970 SBP_LOCK(sdev->target->sbp);
980 sbp_xfer_free(xfer);
971 sbp_xfer_free(xfer);
981 return;
972 SBP_UNLOCK(sdev->target->sbp);
982}
983
984static struct sbp_dev *
985sbp_next_dev(struct sbp_target *target, int lun)
986{
987 struct sbp_dev **sdevp;
988 int i;
989
990 for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun;
991 i++, sdevp++)
992 if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE)
993 return(*sdevp);
994 return(NULL);
995}
996
997#define SCAN_PRI 1
998static void
999sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
1000{
1001 struct sbp_target *target;
1002 struct sbp_dev *sdev;
1003
1004 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
1005 target = sdev->target;
973}
974
975static struct sbp_dev *
976sbp_next_dev(struct sbp_target *target, int lun)
977{
978 struct sbp_dev **sdevp;
979 int i;
980
981 for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun;
982 i++, sdevp++)
983 if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE)
984 return(*sdevp);
985 return(NULL);
986}
987
988#define SCAN_PRI 1
989static void
990sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
991{
992 struct sbp_target *target;
993 struct sbp_dev *sdev;
994
995 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
996 target = sdev->target;
997 SBP_LOCK_ASSERT(target->sbp);
1006SBP_DEBUG(0)
1007 device_printf(sdev->target->sbp->fd.dev,
1008 "%s:%s\n", __func__, sdev->bustgtlun);
1009END_DEBUG
1010 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1011 sdev->status = SBP_DEV_ATTACHED;
1012 } else {
1013 device_printf(sdev->target->sbp->fd.dev,
1014 "%s:%s failed\n", __func__, sdev->bustgtlun);
1015 }
1016 sdev = sbp_next_dev(target, sdev->lun_id + 1);
1017 if (sdev == NULL) {
1018 free(ccb, M_SBP);
1019 return;
1020 }
1021 /* reuse ccb */
1022 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1023 ccb->ccb_h.ccb_sdev_ptr = sdev;
1024 xpt_action(ccb);
1025 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1026 sdev->freeze = 1;
1027}
1028
1029static void
1030sbp_cam_scan_target(void *arg)
1031{
1032 struct sbp_target *target = (struct sbp_target *)arg;
1033 struct sbp_dev *sdev;
1034 union ccb *ccb;
1035
998SBP_DEBUG(0)
999 device_printf(sdev->target->sbp->fd.dev,
1000 "%s:%s\n", __func__, sdev->bustgtlun);
1001END_DEBUG
1002 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1003 sdev->status = SBP_DEV_ATTACHED;
1004 } else {
1005 device_printf(sdev->target->sbp->fd.dev,
1006 "%s:%s failed\n", __func__, sdev->bustgtlun);
1007 }
1008 sdev = sbp_next_dev(target, sdev->lun_id + 1);
1009 if (sdev == NULL) {
1010 free(ccb, M_SBP);
1011 return;
1012 }
1013 /* reuse ccb */
1014 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1015 ccb->ccb_h.ccb_sdev_ptr = sdev;
1016 xpt_action(ccb);
1017 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1018 sdev->freeze = 1;
1019}
1020
1021static void
1022sbp_cam_scan_target(void *arg)
1023{
1024 struct sbp_target *target = (struct sbp_target *)arg;
1025 struct sbp_dev *sdev;
1026 union ccb *ccb;
1027
1028 SBP_LOCK_ASSERT(target->sbp);
1036 sdev = sbp_next_dev(target, 0);
1037 if (sdev == NULL) {
1038 printf("sbp_cam_scan_target: nothing to do for target%d\n",
1039 target->target_id);
1040 return;
1041 }
1042SBP_DEBUG(0)
1043 device_printf(sdev->target->sbp->fd.dev,
1044 "%s:%s\n", __func__, sdev->bustgtlun);
1045END_DEBUG
1046 ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
1047 if (ccb == NULL) {
1048 printf("sbp_cam_scan_target: malloc failed\n");
1049 return;
1050 }
1051 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1052 ccb->ccb_h.func_code = XPT_SCAN_LUN;
1053 ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
1054 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1055 ccb->crcn.flags = CAM_FLAG_NONE;
1056 ccb->ccb_h.ccb_sdev_ptr = sdev;
1057
1058 /* The scan is in progress now. */
1029 sdev = sbp_next_dev(target, 0);
1030 if (sdev == NULL) {
1031 printf("sbp_cam_scan_target: nothing to do for target%d\n",
1032 target->target_id);
1033 return;
1034 }
1035SBP_DEBUG(0)
1036 device_printf(sdev->target->sbp->fd.dev,
1037 "%s:%s\n", __func__, sdev->bustgtlun);
1038END_DEBUG
1039 ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
1040 if (ccb == NULL) {
1041 printf("sbp_cam_scan_target: malloc failed\n");
1042 return;
1043 }
1044 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1045 ccb->ccb_h.func_code = XPT_SCAN_LUN;
1046 ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
1047 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1048 ccb->crcn.flags = CAM_FLAG_NONE;
1049 ccb->ccb_h.ccb_sdev_ptr = sdev;
1050
1051 /* The scan is in progress now. */
1059 SBP_LOCK(target->sbp);
1060 xpt_action(ccb);
1061 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1062 sdev->freeze = 1;
1052 xpt_action(ccb);
1053 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1054 sdev->freeze = 1;
1063 SBP_UNLOCK(target->sbp);
1064}
1065
1066static __inline void
1067sbp_scan_dev(struct sbp_dev *sdev)
1068{
1069 sdev->status = SBP_DEV_PROBE;
1070 callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
1071 sbp_cam_scan_target, (void *)sdev->target);
1072}
1073
1074static void
1075sbp_do_attach(struct fw_xfer *xfer)
1076{
1077 struct sbp_dev *sdev;
1078 struct sbp_target *target;
1079 struct sbp_softc *sbp;
1080
1081 sdev = (struct sbp_dev *)xfer->sc;
1082 target = sdev->target;
1083 sbp = target->sbp;
1055}
1056
1057static __inline void
1058sbp_scan_dev(struct sbp_dev *sdev)
1059{
1060 sdev->status = SBP_DEV_PROBE;
1061 callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
1062 sbp_cam_scan_target, (void *)sdev->target);
1063}
1064
1065static void
1066sbp_do_attach(struct fw_xfer *xfer)
1067{
1068 struct sbp_dev *sdev;
1069 struct sbp_target *target;
1070 struct sbp_softc *sbp;
1071
1072 sdev = (struct sbp_dev *)xfer->sc;
1073 target = sdev->target;
1074 sbp = target->sbp;
1075 SBP_LOCK(sbp);
1084SBP_DEBUG(0)
1085 device_printf(sdev->target->sbp->fd.dev,
1086 "%s:%s\n", __func__, sdev->bustgtlun);
1087END_DEBUG
1088 sbp_xfer_free(xfer);
1089
1090 if (sdev->path == NULL)
1091 xpt_create_path(&sdev->path, NULL,
1092 cam_sim_path(target->sbp->sim),
1093 target->target_id, sdev->lun_id);
1094
1095 /*
1096 * Let CAM scan the bus if we are in the boot process.
1097 * XXX xpt_scan_bus cannot detect LUN larger than 0
1076SBP_DEBUG(0)
1077 device_printf(sdev->target->sbp->fd.dev,
1078 "%s:%s\n", __func__, sdev->bustgtlun);
1079END_DEBUG
1080 sbp_xfer_free(xfer);
1081
1082 if (sdev->path == NULL)
1083 xpt_create_path(&sdev->path, NULL,
1084 cam_sim_path(target->sbp->sim),
1085 target->target_id, sdev->lun_id);
1086
1087 /*
1088 * Let CAM scan the bus if we are in the boot process.
1089 * XXX xpt_scan_bus cannot detect LUN larger than 0
1098 * if LUN 0 doesn't exists.
1090 * if LUN 0 doesn't exist.
1099 */
1100 if (sbp_cold > 0) {
1101 sdev->status = SBP_DEV_ATTACHED;
1091 */
1092 if (sbp_cold > 0) {
1093 sdev->status = SBP_DEV_ATTACHED;
1094 SBP_UNLOCK(sbp);
1102 return;
1103 }
1104
1105 sbp_scan_dev(sdev);
1095 return;
1096 }
1097
1098 sbp_scan_dev(sdev);
1106 return;
1099 SBP_UNLOCK(sbp);
1107}
1108
1109static void
1110sbp_agent_reset_callback(struct fw_xfer *xfer)
1111{
1112 struct sbp_dev *sdev;
1113
1114 sdev = (struct sbp_dev *)xfer->sc;
1115SBP_DEBUG(1)
1116 device_printf(sdev->target->sbp->fd.dev,
1117 "%s:%s\n", __func__, sdev->bustgtlun);
1118END_DEBUG
1119 if (xfer->resp != 0) {
1120 device_printf(sdev->target->sbp->fd.dev,
1121 "%s:%s resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
1122 }
1123
1100}
1101
1102static void
1103sbp_agent_reset_callback(struct fw_xfer *xfer)
1104{
1105 struct sbp_dev *sdev;
1106
1107 sdev = (struct sbp_dev *)xfer->sc;
1108SBP_DEBUG(1)
1109 device_printf(sdev->target->sbp->fd.dev,
1110 "%s:%s\n", __func__, sdev->bustgtlun);
1111END_DEBUG
1112 if (xfer->resp != 0) {
1113 device_printf(sdev->target->sbp->fd.dev,
1114 "%s:%s resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
1115 }
1116
1117 SBP_LOCK(sdev->target->sbp);
1124 sbp_xfer_free(xfer);
1125 if (sdev->path) {
1118 sbp_xfer_free(xfer);
1119 if (sdev->path) {
1126 SBP_LOCK(sdev->target->sbp);
1127 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1128 sdev->freeze = 0;
1120 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1121 sdev->freeze = 0;
1129 SBP_UNLOCK(sdev->target->sbp);
1130 }
1122 }
1123 SBP_UNLOCK(sdev->target->sbp);
1131}
1132
1133static void
1134sbp_agent_reset(struct sbp_dev *sdev)
1135{
1136 struct fw_xfer *xfer;
1137 struct fw_pkt *fp;
1138
1124}
1125
1126static void
1127sbp_agent_reset(struct sbp_dev *sdev)
1128{
1129 struct fw_xfer *xfer;
1130 struct fw_pkt *fp;
1131
1132 SBP_LOCK_ASSERT(sdev->target->sbp);
1139SBP_DEBUG(0)
1140 device_printf(sdev->target->sbp->fd.dev,
1141 "%s:%s\n", __func__, sdev->bustgtlun);
1142END_DEBUG
1143 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
1144 if (xfer == NULL)
1145 return;
1146 if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE)
1147 xfer->hand = sbp_agent_reset_callback;
1148 else
1149 xfer->hand = sbp_do_attach;
1150 fp = &xfer->send.hdr;
1151 fp->mode.wreqq.data = htonl(0xf);
1152 fw_asyreq(xfer->fc, -1, xfer);
1153 sbp_abort_all_ocbs(sdev, CAM_BDR_SENT);
1154}
1155
1156static void
1157sbp_busy_timeout_callback(struct fw_xfer *xfer)
1158{
1159 struct sbp_dev *sdev;
1160
1161 sdev = (struct sbp_dev *)xfer->sc;
1162SBP_DEBUG(1)
1163 device_printf(sdev->target->sbp->fd.dev,
1164 "%s:%s\n", __func__, sdev->bustgtlun);
1165END_DEBUG
1133SBP_DEBUG(0)
1134 device_printf(sdev->target->sbp->fd.dev,
1135 "%s:%s\n", __func__, sdev->bustgtlun);
1136END_DEBUG
1137 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
1138 if (xfer == NULL)
1139 return;
1140 if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE)
1141 xfer->hand = sbp_agent_reset_callback;
1142 else
1143 xfer->hand = sbp_do_attach;
1144 fp = &xfer->send.hdr;
1145 fp->mode.wreqq.data = htonl(0xf);
1146 fw_asyreq(xfer->fc, -1, xfer);
1147 sbp_abort_all_ocbs(sdev, CAM_BDR_SENT);
1148}
1149
1150static void
1151sbp_busy_timeout_callback(struct fw_xfer *xfer)
1152{
1153 struct sbp_dev *sdev;
1154
1155 sdev = (struct sbp_dev *)xfer->sc;
1156SBP_DEBUG(1)
1157 device_printf(sdev->target->sbp->fd.dev,
1158 "%s:%s\n", __func__, sdev->bustgtlun);
1159END_DEBUG
1160 SBP_LOCK(sdev->target->sbp);
1166 sbp_xfer_free(xfer);
1167 sbp_agent_reset(sdev);
1161 sbp_xfer_free(xfer);
1162 sbp_agent_reset(sdev);
1163 SBP_UNLOCK(sdev->target->sbp);
1168}
1169
1170static void
1171sbp_busy_timeout(struct sbp_dev *sdev)
1172{
1173 struct fw_pkt *fp;
1174 struct fw_xfer *xfer;
1175SBP_DEBUG(0)
1176 device_printf(sdev->target->sbp->fd.dev,
1177 "%s:%s\n", __func__, sdev->bustgtlun);
1178END_DEBUG
1179 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
1180
1181 xfer->hand = sbp_busy_timeout_callback;
1182 fp = &xfer->send.hdr;
1183 fp->mode.wreqq.dest_hi = 0xffff;
1184 fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT;
1185 fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
1186 fw_asyreq(xfer->fc, -1, xfer);
1187}
1188
1189static void
1190sbp_orb_pointer_callback(struct fw_xfer *xfer)
1191{
1192 struct sbp_dev *sdev;
1193 sdev = (struct sbp_dev *)xfer->sc;
1194
1195SBP_DEBUG(2)
1196 device_printf(sdev->target->sbp->fd.dev,
1197 "%s:%s\n", __func__, sdev->bustgtlun);
1198END_DEBUG
1199 if (xfer->resp != 0) {
1200 /* XXX */
1201 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1202 }
1164}
1165
1166static void
1167sbp_busy_timeout(struct sbp_dev *sdev)
1168{
1169 struct fw_pkt *fp;
1170 struct fw_xfer *xfer;
1171SBP_DEBUG(0)
1172 device_printf(sdev->target->sbp->fd.dev,
1173 "%s:%s\n", __func__, sdev->bustgtlun);
1174END_DEBUG
1175 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
1176
1177 xfer->hand = sbp_busy_timeout_callback;
1178 fp = &xfer->send.hdr;
1179 fp->mode.wreqq.dest_hi = 0xffff;
1180 fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT;
1181 fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
1182 fw_asyreq(xfer->fc, -1, xfer);
1183}
1184
1185static void
1186sbp_orb_pointer_callback(struct fw_xfer *xfer)
1187{
1188 struct sbp_dev *sdev;
1189 sdev = (struct sbp_dev *)xfer->sc;
1190
1191SBP_DEBUG(2)
1192 device_printf(sdev->target->sbp->fd.dev,
1193 "%s:%s\n", __func__, sdev->bustgtlun);
1194END_DEBUG
1195 if (xfer->resp != 0) {
1196 /* XXX */
1197 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1198 }
1199 SBP_LOCK(sdev->target->sbp);
1203 sbp_xfer_free(xfer);
1204
1200 sbp_xfer_free(xfer);
1201
1205 SBP_LOCK(sdev->target->sbp);
1206 sdev->flags &= ~ORB_POINTER_ACTIVE;
1207
1208 if ((sdev->flags & ORB_POINTER_NEED) != 0) {
1209 struct sbp_ocb *ocb;
1210
1211 sdev->flags &= ~ORB_POINTER_NEED;
1212 ocb = STAILQ_FIRST(&sdev->ocbs);
1213 if (ocb != NULL)
1214 sbp_orb_pointer(sdev, ocb);
1215 }
1216 SBP_UNLOCK(sdev->target->sbp);
1217 return;
1218}
1219
1220static void
1221sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
1222{
1223 struct fw_xfer *xfer;
1224 struct fw_pkt *fp;
1225SBP_DEBUG(1)
1226 device_printf(sdev->target->sbp->fd.dev,
1227 "%s:%s 0x%08x\n",
1228 __func__, sdev->bustgtlun,
1229 (uint32_t)ocb->bus_addr);
1230END_DEBUG
1231
1202 sdev->flags &= ~ORB_POINTER_ACTIVE;
1203
1204 if ((sdev->flags & ORB_POINTER_NEED) != 0) {
1205 struct sbp_ocb *ocb;
1206
1207 sdev->flags &= ~ORB_POINTER_NEED;
1208 ocb = STAILQ_FIRST(&sdev->ocbs);
1209 if (ocb != NULL)
1210 sbp_orb_pointer(sdev, ocb);
1211 }
1212 SBP_UNLOCK(sdev->target->sbp);
1213 return;
1214}
1215
1216static void
1217sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
1218{
1219 struct fw_xfer *xfer;
1220 struct fw_pkt *fp;
1221SBP_DEBUG(1)
1222 device_printf(sdev->target->sbp->fd.dev,
1223 "%s:%s 0x%08x\n",
1224 __func__, sdev->bustgtlun,
1225 (uint32_t)ocb->bus_addr);
1226END_DEBUG
1227
1232 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
1228 SBP_LOCK_ASSERT(sdev->target->sbp);
1233
1234 if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
1235SBP_DEBUG(0)
1236 printf("%s: orb pointer active\n", __func__);
1237END_DEBUG
1238 sdev->flags |= ORB_POINTER_NEED;
1239 return;
1240 }
1241
1242 sdev->flags |= ORB_POINTER_ACTIVE;
1229
1230 if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
1231SBP_DEBUG(0)
1232 printf("%s: orb pointer active\n", __func__);
1233END_DEBUG
1234 sdev->flags |= ORB_POINTER_NEED;
1235 return;
1236 }
1237
1238 sdev->flags |= ORB_POINTER_ACTIVE;
1243 xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQB, 0x08);
1239 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08);
1244 if (xfer == NULL)
1245 return;
1246 xfer->hand = sbp_orb_pointer_callback;
1247
1248 fp = &xfer->send.hdr;
1249 fp->mode.wreqb.len = 8;
1250 fp->mode.wreqb.extcode = 0;
1251 xfer->send.payload[0] =
1252 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
1253 xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
1254
1240 if (xfer == NULL)
1241 return;
1242 xfer->hand = sbp_orb_pointer_callback;
1243
1244 fp = &xfer->send.hdr;
1245 fp->mode.wreqb.len = 8;
1246 fp->mode.wreqb.extcode = 0;
1247 xfer->send.payload[0] =
1248 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
1249 xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
1250
1255 /*
1256 * sbp_xfer_free() will attempt to acquire
1257 * the SBP lock on entrance. Also, this removes
1258 * a LOR between the firewire layer and sbp
1259 */
1260 SBP_UNLOCK(sdev->target->sbp);
1261 if(fw_asyreq(xfer->fc, -1, xfer) != 0){
1262 sbp_xfer_free(xfer);
1263 ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
1264 xpt_done(ocb->ccb);
1251 if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
1252 sbp_xfer_free(xfer);
1253 ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
1254 xpt_done(ocb->ccb);
1265 }
1255 }
1266 SBP_LOCK(sdev->target->sbp);
1267}
1268
1269static void
1270sbp_doorbell_callback(struct fw_xfer *xfer)
1271{
1272 struct sbp_dev *sdev;
1273 sdev = (struct sbp_dev *)xfer->sc;
1274
1275SBP_DEBUG(1)
1276 device_printf(sdev->target->sbp->fd.dev,
1277 "%s:%s\n", __func__, sdev->bustgtlun);
1278END_DEBUG
1279 if (xfer->resp != 0) {
1280 /* XXX */
1281 device_printf(sdev->target->sbp->fd.dev,
1282 "%s: xfer->resp = %d\n", __func__, xfer->resp);
1283 }
1256}
1257
1258static void
1259sbp_doorbell_callback(struct fw_xfer *xfer)
1260{
1261 struct sbp_dev *sdev;
1262 sdev = (struct sbp_dev *)xfer->sc;
1263
1264SBP_DEBUG(1)
1265 device_printf(sdev->target->sbp->fd.dev,
1266 "%s:%s\n", __func__, sdev->bustgtlun);
1267END_DEBUG
1268 if (xfer->resp != 0) {
1269 /* XXX */
1270 device_printf(sdev->target->sbp->fd.dev,
1271 "%s: xfer->resp = %d\n", __func__, xfer->resp);
1272 }
1273 SBP_LOCK(sdev->target->sbp);
1284 sbp_xfer_free(xfer);
1285 sdev->flags &= ~ORB_DOORBELL_ACTIVE;
1286 if ((sdev->flags & ORB_DOORBELL_NEED) != 0) {
1287 sdev->flags &= ~ORB_DOORBELL_NEED;
1274 sbp_xfer_free(xfer);
1275 sdev->flags &= ~ORB_DOORBELL_ACTIVE;
1276 if ((sdev->flags & ORB_DOORBELL_NEED) != 0) {
1277 sdev->flags &= ~ORB_DOORBELL_NEED;
1288 SBP_LOCK(sdev->target->sbp);
1289 sbp_doorbell(sdev);
1278 sbp_doorbell(sdev);
1290 SBP_UNLOCK(sdev->target->sbp);
1291 }
1279 }
1292 return;
1280 SBP_UNLOCK(sdev->target->sbp);
1293}
1294
1295static void
1296sbp_doorbell(struct sbp_dev *sdev)
1297{
1298 struct fw_xfer *xfer;
1299 struct fw_pkt *fp;
1300SBP_DEBUG(1)
1301 device_printf(sdev->target->sbp->fd.dev,
1302 "%s:%s\n", __func__, sdev->bustgtlun);
1303END_DEBUG
1304
1305 if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
1306 sdev->flags |= ORB_DOORBELL_NEED;
1307 return;
1308 }
1309 sdev->flags |= ORB_DOORBELL_ACTIVE;
1281}
1282
1283static void
1284sbp_doorbell(struct sbp_dev *sdev)
1285{
1286 struct fw_xfer *xfer;
1287 struct fw_pkt *fp;
1288SBP_DEBUG(1)
1289 device_printf(sdev->target->sbp->fd.dev,
1290 "%s:%s\n", __func__, sdev->bustgtlun);
1291END_DEBUG
1292
1293 if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
1294 sdev->flags |= ORB_DOORBELL_NEED;
1295 return;
1296 }
1297 sdev->flags |= ORB_DOORBELL_ACTIVE;
1310 xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQQ, 0x10);
1298 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10);
1311 if (xfer == NULL)
1312 return;
1313 xfer->hand = sbp_doorbell_callback;
1314 fp = &xfer->send.hdr;
1315 fp->mode.wreqq.data = htonl(0xf);
1316 fw_asyreq(xfer->fc, -1, xfer);
1317}
1318
1319static struct fw_xfer *
1299 if (xfer == NULL)
1300 return;
1301 xfer->hand = sbp_doorbell_callback;
1302 fp = &xfer->send.hdr;
1303 fp->mode.wreqq.data = htonl(0xf);
1304 fw_asyreq(xfer->fc, -1, xfer);
1305}
1306
1307static struct fw_xfer *
1320sbp_write_cmd_locked(struct sbp_dev *sdev, int tcode, int offset)
1308sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1321{
1322 struct fw_xfer *xfer;
1323 struct fw_pkt *fp;
1324 struct sbp_target *target;
1309{
1310 struct fw_xfer *xfer;
1311 struct fw_pkt *fp;
1312 struct sbp_target *target;
1325 int s, new = 0;
1313 int new = 0;
1326
1314
1327 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
1315 SBP_LOCK_ASSERT(sdev->target->sbp);
1328
1329 target = sdev->target;
1316
1317 target = sdev->target;
1330 s = splfw();
1331 xfer = STAILQ_FIRST(&target->xferlist);
1332 if (xfer == NULL) {
1333 if (target->n_xfer > 5 /* XXX */) {
1334 printf("sbp: no more xfer for this target\n");
1318 xfer = STAILQ_FIRST(&target->xferlist);
1319 if (xfer == NULL) {
1320 if (target->n_xfer > 5 /* XXX */) {
1321 printf("sbp: no more xfer for this target\n");
1335 splx(s);
1336 return(NULL);
1337 }
1338 xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
1339 if(xfer == NULL){
1340 printf("sbp: fw_xfer_alloc_buf failed\n");
1322 return(NULL);
1323 }
1324 xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
1325 if(xfer == NULL){
1326 printf("sbp: fw_xfer_alloc_buf failed\n");
1341 splx(s);
1342 return NULL;
1343 }
1344 target->n_xfer ++;
1345 if (debug)
1346 printf("sbp: alloc %d xfer\n", target->n_xfer);
1347 new = 1;
1348 } else {
1349 STAILQ_REMOVE_HEAD(&target->xferlist, link);
1350 }
1327 return NULL;
1328 }
1329 target->n_xfer ++;
1330 if (debug)
1331 printf("sbp: alloc %d xfer\n", target->n_xfer);
1332 new = 1;
1333 } else {
1334 STAILQ_REMOVE_HEAD(&target->xferlist, link);
1335 }
1351 splx(s);
1352
1353 if (new) {
1354 xfer->recv.pay_len = 0;
1355 xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
1356 xfer->fc = sdev->target->sbp->fd.fc;
1357 }
1358
1359 if (tcode == FWTCODE_WREQB)
1360 xfer->send.pay_len = 8;
1361 else
1362 xfer->send.pay_len = 0;
1363
1364 xfer->sc = (caddr_t)sdev;
1365 fp = &xfer->send.hdr;
1366 fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
1367 fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
1368 fp->mode.wreqq.tlrt = 0;
1369 fp->mode.wreqq.tcode = tcode;
1370 fp->mode.wreqq.pri = 0;
1371 fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
1372
1373 return xfer;
1336
1337 if (new) {
1338 xfer->recv.pay_len = 0;
1339 xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
1340 xfer->fc = sdev->target->sbp->fd.fc;
1341 }
1342
1343 if (tcode == FWTCODE_WREQB)
1344 xfer->send.pay_len = 8;
1345 else
1346 xfer->send.pay_len = 0;
1347
1348 xfer->sc = (caddr_t)sdev;
1349 fp = &xfer->send.hdr;
1350 fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
1351 fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
1352 fp->mode.wreqq.tlrt = 0;
1353 fp->mode.wreqq.tcode = tcode;
1354 fp->mode.wreqq.pri = 0;
1355 fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
1356
1357 return xfer;
1374
1375}
1376
1358}
1359
1377static struct fw_xfer *
1378sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1379{
1380 struct sbp_softc *sbp = sdev->target->sbp;
1381 struct fw_xfer *xfer;
1382
1383 SBP_LOCK(sbp);
1384 xfer = sbp_write_cmd_locked(sdev, tcode, offset);
1385 SBP_UNLOCK(sbp);
1386
1387 return (xfer);
1388}
1389
1390static void
1391sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
1392{
1393 struct fw_xfer *xfer;
1394 struct fw_pkt *fp;
1395 struct sbp_ocb *ocb;
1396 struct sbp_target *target;
1360static void
1361sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
1362{
1363 struct fw_xfer *xfer;
1364 struct fw_pkt *fp;
1365 struct sbp_ocb *ocb;
1366 struct sbp_target *target;
1397 int s, nid;
1367 int nid;
1398
1399 target = sdev->target;
1400 nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
1401
1368
1369 target = sdev->target;
1370 nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
1371
1402 s = splfw();
1403 SBP_LOCK(target->sbp);
1372 SBP_LOCK_ASSERT(target->sbp);
1404 if (func == ORB_FUN_RUNQUEUE) {
1405 ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
1406 if (target->mgm_ocb_cur != NULL || ocb == NULL) {
1373 if (func == ORB_FUN_RUNQUEUE) {
1374 ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
1375 if (target->mgm_ocb_cur != NULL || ocb == NULL) {
1407 SBP_UNLOCK(target->sbp);
1408 splx(s);
1409 return;
1410 }
1411 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
1376 return;
1377 }
1378 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
1412 SBP_UNLOCK(target->sbp);
1413 goto start;
1414 }
1415 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
1379 goto start;
1380 }
1381 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
1416 SBP_UNLOCK(target->sbp);
1417 splx(s);
1418 /* XXX */
1419 return;
1420 }
1382 /* XXX */
1383 return;
1384 }
1421 SBP_UNLOCK(target->sbp);
1422 ocb->flags = OCB_ACT_MGM;
1423 ocb->sdev = sdev;
1424
1425 bzero((void *)ocb->orb, sizeof(ocb->orb));
1426 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1427 ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id));
1428
1429SBP_DEBUG(0)
1430 device_printf(sdev->target->sbp->fd.dev,
1431 "%s:%s %s\n",
1432 __func__,sdev->bustgtlun,
1433 orb_fun_name[(func>>16)&0xf]);
1434END_DEBUG
1435 switch (func) {
1436 case ORB_FUN_LGI:
1437 ocb->orb[0] = ocb->orb[1] = 0; /* password */
1438 ocb->orb[2] = htonl(nid << 16);
1439 ocb->orb[3] = htonl(sdev->dma.bus_addr);
1440 ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
1441 if (ex_login)
1442 ocb->orb[4] |= htonl(ORB_EXV);
1443 ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
1444 fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD);
1445 break;
1446 case ORB_FUN_ATA:
1447 ocb->orb[0] = htonl((0 << 16) | 0);
1448 ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff);
1449 /* fall through */
1450 case ORB_FUN_RCN:
1451 case ORB_FUN_LGO:
1452 case ORB_FUN_LUR:
1453 case ORB_FUN_RST:
1454 case ORB_FUN_ATS:
1455 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
1456 break;
1457 }
1458
1459 if (target->mgm_ocb_cur != NULL) {
1460 /* there is a standing ORB */
1385 ocb->flags = OCB_ACT_MGM;
1386 ocb->sdev = sdev;
1387
1388 bzero((void *)ocb->orb, sizeof(ocb->orb));
1389 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1390 ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id));
1391
1392SBP_DEBUG(0)
1393 device_printf(sdev->target->sbp->fd.dev,
1394 "%s:%s %s\n",
1395 __func__,sdev->bustgtlun,
1396 orb_fun_name[(func>>16)&0xf]);
1397END_DEBUG
1398 switch (func) {
1399 case ORB_FUN_LGI:
1400 ocb->orb[0] = ocb->orb[1] = 0; /* password */
1401 ocb->orb[2] = htonl(nid << 16);
1402 ocb->orb[3] = htonl(sdev->dma.bus_addr);
1403 ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
1404 if (ex_login)
1405 ocb->orb[4] |= htonl(ORB_EXV);
1406 ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
1407 fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD);
1408 break;
1409 case ORB_FUN_ATA:
1410 ocb->orb[0] = htonl((0 << 16) | 0);
1411 ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff);
1412 /* fall through */
1413 case ORB_FUN_RCN:
1414 case ORB_FUN_LGO:
1415 case ORB_FUN_LUR:
1416 case ORB_FUN_RST:
1417 case ORB_FUN_ATS:
1418 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
1419 break;
1420 }
1421
1422 if (target->mgm_ocb_cur != NULL) {
1423 /* there is a standing ORB */
1461 SBP_LOCK(target->sbp);
1462 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
1424 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
1463 SBP_UNLOCK(target->sbp);
1464 splx(s);
1465 return;
1466 }
1467start:
1468 target->mgm_ocb_cur = ocb;
1425 return;
1426 }
1427start:
1428 target->mgm_ocb_cur = ocb;
1469 splx(s);
1470
1471 callout_reset(&target->mgm_ocb_timeout, 5*hz,
1472 sbp_mgm_timeout, (caddr_t)ocb);
1473 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1474 if(xfer == NULL){
1475 return;
1476 }
1477 xfer->hand = sbp_mgm_callback;
1478
1479 fp = &xfer->send.hdr;
1480 fp->mode.wreqb.dest_hi = sdev->target->mgm_hi;
1481 fp->mode.wreqb.dest_lo = sdev->target->mgm_lo;
1482 fp->mode.wreqb.len = 8;
1483 fp->mode.wreqb.extcode = 0;
1484 xfer->send.payload[0] = htonl(nid << 16);
1485 xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff);
1486
1487 fw_asyreq(xfer->fc, -1, xfer);
1488}
1489
1490static void
1491sbp_print_scsi_cmd(struct sbp_ocb *ocb)
1492{
1493 struct ccb_scsiio *csio;
1494
1495 csio = &ocb->ccb->csio;
1496 printf("%s:%d:%jx XPT_SCSI_IO: "
1497 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1498 ", flags: 0x%02x, "
1499 "%db cmd/%db data/%db sense\n",
1500 device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
1501 ocb->ccb->ccb_h.target_id,
1502 (uintmax_t)ocb->ccb->ccb_h.target_lun,
1503 csio->cdb_io.cdb_bytes[0],
1504 csio->cdb_io.cdb_bytes[1],
1505 csio->cdb_io.cdb_bytes[2],
1506 csio->cdb_io.cdb_bytes[3],
1507 csio->cdb_io.cdb_bytes[4],
1508 csio->cdb_io.cdb_bytes[5],
1509 csio->cdb_io.cdb_bytes[6],
1510 csio->cdb_io.cdb_bytes[7],
1511 csio->cdb_io.cdb_bytes[8],
1512 csio->cdb_io.cdb_bytes[9],
1513 ocb->ccb->ccb_h.flags & CAM_DIR_MASK,
1514 csio->cdb_len, csio->dxfer_len,
1515 csio->sense_len);
1516}
1517
1518static void
1519sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
1520{
1521 struct sbp_cmd_status *sbp_cmd_status;
1522 struct scsi_sense_data_fixed *sense;
1523
1524 sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
1525 sense = (struct scsi_sense_data_fixed *)&ocb->ccb->csio.sense_data;
1526
1527SBP_DEBUG(0)
1528 sbp_print_scsi_cmd(ocb);
1529 /* XXX need decode status */
1530 printf("%s: SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
1531 ocb->sdev->bustgtlun,
1532 sbp_cmd_status->status,
1533 sbp_cmd_status->sfmt,
1534 sbp_cmd_status->valid,
1535 sbp_cmd_status->s_key,
1536 sbp_cmd_status->s_code,
1537 sbp_cmd_status->s_qlfr,
1538 sbp_status->len);
1539END_DEBUG
1540
1541 switch (sbp_cmd_status->status) {
1542 case SCSI_STATUS_CHECK_COND:
1543 case SCSI_STATUS_BUSY:
1544 case SCSI_STATUS_CMD_TERMINATED:
1545 if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
1546 sense->error_code = SSD_CURRENT_ERROR;
1547 }else{
1548 sense->error_code = SSD_DEFERRED_ERROR;
1549 }
1550 if(sbp_cmd_status->valid)
1551 sense->error_code |= SSD_ERRCODE_VALID;
1552 sense->flags = sbp_cmd_status->s_key;
1553 if(sbp_cmd_status->mark)
1554 sense->flags |= SSD_FILEMARK;
1555 if(sbp_cmd_status->eom)
1556 sense->flags |= SSD_EOM;
1557 if(sbp_cmd_status->ill_len)
1558 sense->flags |= SSD_ILI;
1559
1560 bcopy(&sbp_cmd_status->info, &sense->info[0], 4);
1561
1562 if (sbp_status->len <= 1)
1563 /* XXX not scsi status. shouldn't be happened */
1564 sense->extra_len = 0;
1565 else if (sbp_status->len <= 4)
1566 /* add_sense_code(_qual), info, cmd_spec_info */
1567 sense->extra_len = 6;
1568 else
1569 /* fru, sense_key_spec */
1570 sense->extra_len = 10;
1571
1572 bcopy(&sbp_cmd_status->cdb, &sense->cmd_spec_info[0], 4);
1573
1574 sense->add_sense_code = sbp_cmd_status->s_code;
1575 sense->add_sense_code_qual = sbp_cmd_status->s_qlfr;
1576 sense->fru = sbp_cmd_status->fru;
1577
1578 bcopy(&sbp_cmd_status->s_keydep[0],
1579 &sense->sense_key_spec[0], 3);
1580
1581 ocb->ccb->csio.scsi_status = sbp_cmd_status->status;
1582 ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
1583 | CAM_AUTOSNS_VALID;
1584/*
1585{
1586 uint8_t j, *tmp;
1587 tmp = sense;
1588 for( j = 0 ; j < 32 ; j+=8){
1589 printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
1590 tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
1591 tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
1592 }
1593
1594}
1595*/
1596 break;
1597 default:
1598 device_printf(ocb->sdev->target->sbp->fd.dev,
1599 "%s:%s unknown scsi status 0x%x\n",
1600 __func__, ocb->sdev->bustgtlun,
1601 sbp_cmd_status->status);
1602 }
1603}
1604
1605static void
1606sbp_fix_inq_data(struct sbp_ocb *ocb)
1607{
1608 union ccb *ccb;
1609 struct sbp_dev *sdev;
1610 struct scsi_inquiry_data *inq;
1611
1612 ccb = ocb->ccb;
1613 sdev = ocb->sdev;
1614
1615 if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD)
1616 return;
1617SBP_DEBUG(1)
1618 device_printf(sdev->target->sbp->fd.dev,
1619 "%s:%s\n", __func__, sdev->bustgtlun);
1620END_DEBUG
1621 inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr;
1622 switch (SID_TYPE(inq)) {
1623 case T_DIRECT:
1624#if 0
1625 /*
1626 * XXX Convert Direct Access device to RBC.
1627 * I've never seen FireWire DA devices which support READ_6.
1628 */
1629 if (SID_TYPE(inq) == T_DIRECT)
1630 inq->device |= T_RBC; /* T_DIRECT == 0 */
1631#endif
1632 /* fall through */
1633 case T_RBC:
1634 /*
1635 * Override vendor/product/revision information.
1636 * Some devices sometimes return strange strings.
1637 */
1638#if 1
1639 bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
1640 bcopy(sdev->product, inq->product, sizeof(inq->product));
1641 bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
1642#endif
1643 break;
1644 }
1645 /*
1646 * Force to enable/disable tagged queuing.
1647 * XXX CAM also checks SCP_QUEUE_DQUE flag in the control mode page.
1648 */
1649 if (sbp_tags > 0)
1650 inq->flags |= SID_CmdQue;
1651 else if (sbp_tags < 0)
1652 inq->flags &= ~SID_CmdQue;
1653
1654}
1655
1656static void
1657sbp_recv1(struct fw_xfer *xfer)
1658{
1659 struct fw_pkt *rfp;
1660#if NEED_RESPONSE
1661 struct fw_pkt *sfp;
1662#endif
1663 struct sbp_softc *sbp;
1664 struct sbp_dev *sdev;
1665 struct sbp_ocb *ocb;
1666 struct sbp_login_res *login_res = NULL;
1667 struct sbp_status *sbp_status;
1668 struct sbp_target *target;
1669 int orb_fun, status_valid0, status_valid, t, l, reset_agent = 0;
1670 uint32_t addr;
1671/*
1672 uint32_t *ld;
1673 ld = xfer->recv.buf;
1674printf("sbp %x %d %d %08x %08x %08x %08x\n",
1675 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1676printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1677printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1678*/
1679 sbp = (struct sbp_softc *)xfer->sc;
1429
1430 callout_reset(&target->mgm_ocb_timeout, 5*hz,
1431 sbp_mgm_timeout, (caddr_t)ocb);
1432 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1433 if(xfer == NULL){
1434 return;
1435 }
1436 xfer->hand = sbp_mgm_callback;
1437
1438 fp = &xfer->send.hdr;
1439 fp->mode.wreqb.dest_hi = sdev->target->mgm_hi;
1440 fp->mode.wreqb.dest_lo = sdev->target->mgm_lo;
1441 fp->mode.wreqb.len = 8;
1442 fp->mode.wreqb.extcode = 0;
1443 xfer->send.payload[0] = htonl(nid << 16);
1444 xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff);
1445
1446 fw_asyreq(xfer->fc, -1, xfer);
1447}
1448
1449static void
1450sbp_print_scsi_cmd(struct sbp_ocb *ocb)
1451{
1452 struct ccb_scsiio *csio;
1453
1454 csio = &ocb->ccb->csio;
1455 printf("%s:%d:%jx XPT_SCSI_IO: "
1456 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1457 ", flags: 0x%02x, "
1458 "%db cmd/%db data/%db sense\n",
1459 device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
1460 ocb->ccb->ccb_h.target_id,
1461 (uintmax_t)ocb->ccb->ccb_h.target_lun,
1462 csio->cdb_io.cdb_bytes[0],
1463 csio->cdb_io.cdb_bytes[1],
1464 csio->cdb_io.cdb_bytes[2],
1465 csio->cdb_io.cdb_bytes[3],
1466 csio->cdb_io.cdb_bytes[4],
1467 csio->cdb_io.cdb_bytes[5],
1468 csio->cdb_io.cdb_bytes[6],
1469 csio->cdb_io.cdb_bytes[7],
1470 csio->cdb_io.cdb_bytes[8],
1471 csio->cdb_io.cdb_bytes[9],
1472 ocb->ccb->ccb_h.flags & CAM_DIR_MASK,
1473 csio->cdb_len, csio->dxfer_len,
1474 csio->sense_len);
1475}
1476
1477static void
1478sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
1479{
1480 struct sbp_cmd_status *sbp_cmd_status;
1481 struct scsi_sense_data_fixed *sense;
1482
1483 sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
1484 sense = (struct scsi_sense_data_fixed *)&ocb->ccb->csio.sense_data;
1485
1486SBP_DEBUG(0)
1487 sbp_print_scsi_cmd(ocb);
1488 /* XXX need decode status */
1489 printf("%s: SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
1490 ocb->sdev->bustgtlun,
1491 sbp_cmd_status->status,
1492 sbp_cmd_status->sfmt,
1493 sbp_cmd_status->valid,
1494 sbp_cmd_status->s_key,
1495 sbp_cmd_status->s_code,
1496 sbp_cmd_status->s_qlfr,
1497 sbp_status->len);
1498END_DEBUG
1499
1500 switch (sbp_cmd_status->status) {
1501 case SCSI_STATUS_CHECK_COND:
1502 case SCSI_STATUS_BUSY:
1503 case SCSI_STATUS_CMD_TERMINATED:
1504 if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
1505 sense->error_code = SSD_CURRENT_ERROR;
1506 }else{
1507 sense->error_code = SSD_DEFERRED_ERROR;
1508 }
1509 if(sbp_cmd_status->valid)
1510 sense->error_code |= SSD_ERRCODE_VALID;
1511 sense->flags = sbp_cmd_status->s_key;
1512 if(sbp_cmd_status->mark)
1513 sense->flags |= SSD_FILEMARK;
1514 if(sbp_cmd_status->eom)
1515 sense->flags |= SSD_EOM;
1516 if(sbp_cmd_status->ill_len)
1517 sense->flags |= SSD_ILI;
1518
1519 bcopy(&sbp_cmd_status->info, &sense->info[0], 4);
1520
1521 if (sbp_status->len <= 1)
1522 /* XXX not scsi status. shouldn't be happened */
1523 sense->extra_len = 0;
1524 else if (sbp_status->len <= 4)
1525 /* add_sense_code(_qual), info, cmd_spec_info */
1526 sense->extra_len = 6;
1527 else
1528 /* fru, sense_key_spec */
1529 sense->extra_len = 10;
1530
1531 bcopy(&sbp_cmd_status->cdb, &sense->cmd_spec_info[0], 4);
1532
1533 sense->add_sense_code = sbp_cmd_status->s_code;
1534 sense->add_sense_code_qual = sbp_cmd_status->s_qlfr;
1535 sense->fru = sbp_cmd_status->fru;
1536
1537 bcopy(&sbp_cmd_status->s_keydep[0],
1538 &sense->sense_key_spec[0], 3);
1539
1540 ocb->ccb->csio.scsi_status = sbp_cmd_status->status;
1541 ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
1542 | CAM_AUTOSNS_VALID;
1543/*
1544{
1545 uint8_t j, *tmp;
1546 tmp = sense;
1547 for( j = 0 ; j < 32 ; j+=8){
1548 printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
1549 tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
1550 tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
1551 }
1552
1553}
1554*/
1555 break;
1556 default:
1557 device_printf(ocb->sdev->target->sbp->fd.dev,
1558 "%s:%s unknown scsi status 0x%x\n",
1559 __func__, ocb->sdev->bustgtlun,
1560 sbp_cmd_status->status);
1561 }
1562}
1563
1564static void
1565sbp_fix_inq_data(struct sbp_ocb *ocb)
1566{
1567 union ccb *ccb;
1568 struct sbp_dev *sdev;
1569 struct scsi_inquiry_data *inq;
1570
1571 ccb = ocb->ccb;
1572 sdev = ocb->sdev;
1573
1574 if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD)
1575 return;
1576SBP_DEBUG(1)
1577 device_printf(sdev->target->sbp->fd.dev,
1578 "%s:%s\n", __func__, sdev->bustgtlun);
1579END_DEBUG
1580 inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr;
1581 switch (SID_TYPE(inq)) {
1582 case T_DIRECT:
1583#if 0
1584 /*
1585 * XXX Convert Direct Access device to RBC.
1586 * I've never seen FireWire DA devices which support READ_6.
1587 */
1588 if (SID_TYPE(inq) == T_DIRECT)
1589 inq->device |= T_RBC; /* T_DIRECT == 0 */
1590#endif
1591 /* fall through */
1592 case T_RBC:
1593 /*
1594 * Override vendor/product/revision information.
1595 * Some devices sometimes return strange strings.
1596 */
1597#if 1
1598 bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
1599 bcopy(sdev->product, inq->product, sizeof(inq->product));
1600 bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
1601#endif
1602 break;
1603 }
1604 /*
1605 * Force to enable/disable tagged queuing.
1606 * XXX CAM also checks SCP_QUEUE_DQUE flag in the control mode page.
1607 */
1608 if (sbp_tags > 0)
1609 inq->flags |= SID_CmdQue;
1610 else if (sbp_tags < 0)
1611 inq->flags &= ~SID_CmdQue;
1612
1613}
1614
1615static void
1616sbp_recv1(struct fw_xfer *xfer)
1617{
1618 struct fw_pkt *rfp;
1619#if NEED_RESPONSE
1620 struct fw_pkt *sfp;
1621#endif
1622 struct sbp_softc *sbp;
1623 struct sbp_dev *sdev;
1624 struct sbp_ocb *ocb;
1625 struct sbp_login_res *login_res = NULL;
1626 struct sbp_status *sbp_status;
1627 struct sbp_target *target;
1628 int orb_fun, status_valid0, status_valid, t, l, reset_agent = 0;
1629 uint32_t addr;
1630/*
1631 uint32_t *ld;
1632 ld = xfer->recv.buf;
1633printf("sbp %x %d %d %08x %08x %08x %08x\n",
1634 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1635printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1636printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1637*/
1638 sbp = (struct sbp_softc *)xfer->sc;
1639 SBP_LOCK_ASSERT(sbp);
1680 if (xfer->resp != 0){
1681 printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
1682 goto done0;
1683 }
1684 if (xfer->recv.payload == NULL){
1685 printf("sbp_recv: xfer->recv.payload == NULL\n");
1686 goto done0;
1687 }
1688 rfp = &xfer->recv.hdr;
1689 if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
1690 printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
1691 goto done0;
1692 }
1693 sbp_status = (struct sbp_status *)xfer->recv.payload;
1694 addr = rfp->mode.wreqb.dest_lo;
1695SBP_DEBUG(2)
1696 printf("received address 0x%x\n", addr);
1697END_DEBUG
1698 t = SBP_ADDR2TRG(addr);
1699 if (t >= SBP_NUM_TARGETS) {
1700 device_printf(sbp->fd.dev,
1701 "sbp_recv1: invalid target %d\n", t);
1702 goto done0;
1703 }
1704 target = &sbp->targets[t];
1705 l = SBP_ADDR2LUN(addr);
1706 if (l >= target->num_lun || target->luns[l] == NULL) {
1707 device_printf(sbp->fd.dev,
1708 "sbp_recv1: invalid lun %d (target=%d)\n", l, t);
1709 goto done0;
1710 }
1711 sdev = target->luns[l];
1712
1713 ocb = NULL;
1714 switch (sbp_status->src) {
1715 case 0:
1716 case 1:
1717 /* check mgm_ocb_cur first */
1718 ocb = target->mgm_ocb_cur;
1719 if (ocb != NULL) {
1720 if (OCB_MATCH(ocb, sbp_status)) {
1721 callout_stop(&target->mgm_ocb_timeout);
1722 target->mgm_ocb_cur = NULL;
1723 break;
1724 }
1725 }
1726 ocb = sbp_dequeue_ocb(sdev, sbp_status);
1727 if (ocb == NULL) {
1728 device_printf(sdev->target->sbp->fd.dev,
1729#if defined(__DragonFly__) || __FreeBSD_version < 500000
1730 "%s:%s No ocb(%lx) on the queue\n",
1731#else
1732 "%s:%s No ocb(%x) on the queue\n",
1733#endif
1734 __func__,sdev->bustgtlun,
1735 ntohl(sbp_status->orb_lo));
1736 }
1737 break;
1738 case 2:
1739 /* unsolicit */
1740 device_printf(sdev->target->sbp->fd.dev,
1741 "%s:%s unsolicit status received\n",
1742 __func__, sdev->bustgtlun);
1743 break;
1744 default:
1745 device_printf(sdev->target->sbp->fd.dev,
1746 "%s:%s unknown sbp_status->src\n",
1747 __func__, sdev->bustgtlun);
1748 }
1749
1750 status_valid0 = (sbp_status->src < 2
1751 && sbp_status->resp == ORB_RES_CMPL
1752 && sbp_status->dead == 0);
1753 status_valid = (status_valid0 && sbp_status->status == 0);
1754
1755 if (!status_valid0 || debug > 2){
1756 int status;
1757SBP_DEBUG(0)
1758 device_printf(sdev->target->sbp->fd.dev,
1759 "%s:%s ORB status src:%x resp:%x dead:%x"
1760#if defined(__DragonFly__) || __FreeBSD_version < 500000
1761 " len:%x stat:%x orb:%x%08lx\n",
1762#else
1763 " len:%x stat:%x orb:%x%08x\n",
1764#endif
1765 __func__, sdev->bustgtlun,
1766 sbp_status->src, sbp_status->resp, sbp_status->dead,
1767 sbp_status->len, sbp_status->status,
1768 ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
1769END_DEBUG
1770 device_printf(sdev->target->sbp->fd.dev,
1771 "%s\n", sdev->bustgtlun);
1772 status = sbp_status->status;
1773 switch(sbp_status->resp) {
1774 case 0:
1775 if (status > MAX_ORB_STATUS0)
1776 printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
1777 else
1778 printf("%s\n", orb_status0[status]);
1779 break;
1780 case 1:
1781 printf("Obj: %s, Error: %s\n",
1782 orb_status1_object[(status>>6) & 3],
1783 orb_status1_serial_bus_error[status & 0xf]);
1784 break;
1785 case 2:
1786 printf("Illegal request\n");
1787 break;
1788 case 3:
1789 printf("Vendor dependent\n");
1790 break;
1791 default:
1792 printf("unknown respose code %d\n", sbp_status->resp);
1793 }
1794 }
1795
1796 /* we have to reset the fetch agent if it's dead */
1797 if (sbp_status->dead) {
1798 if (sdev->path) {
1640 if (xfer->resp != 0){
1641 printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
1642 goto done0;
1643 }
1644 if (xfer->recv.payload == NULL){
1645 printf("sbp_recv: xfer->recv.payload == NULL\n");
1646 goto done0;
1647 }
1648 rfp = &xfer->recv.hdr;
1649 if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
1650 printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
1651 goto done0;
1652 }
1653 sbp_status = (struct sbp_status *)xfer->recv.payload;
1654 addr = rfp->mode.wreqb.dest_lo;
1655SBP_DEBUG(2)
1656 printf("received address 0x%x\n", addr);
1657END_DEBUG
1658 t = SBP_ADDR2TRG(addr);
1659 if (t >= SBP_NUM_TARGETS) {
1660 device_printf(sbp->fd.dev,
1661 "sbp_recv1: invalid target %d\n", t);
1662 goto done0;
1663 }
1664 target = &sbp->targets[t];
1665 l = SBP_ADDR2LUN(addr);
1666 if (l >= target->num_lun || target->luns[l] == NULL) {
1667 device_printf(sbp->fd.dev,
1668 "sbp_recv1: invalid lun %d (target=%d)\n", l, t);
1669 goto done0;
1670 }
1671 sdev = target->luns[l];
1672
1673 ocb = NULL;
1674 switch (sbp_status->src) {
1675 case 0:
1676 case 1:
1677 /* check mgm_ocb_cur first */
1678 ocb = target->mgm_ocb_cur;
1679 if (ocb != NULL) {
1680 if (OCB_MATCH(ocb, sbp_status)) {
1681 callout_stop(&target->mgm_ocb_timeout);
1682 target->mgm_ocb_cur = NULL;
1683 break;
1684 }
1685 }
1686 ocb = sbp_dequeue_ocb(sdev, sbp_status);
1687 if (ocb == NULL) {
1688 device_printf(sdev->target->sbp->fd.dev,
1689#if defined(__DragonFly__) || __FreeBSD_version < 500000
1690 "%s:%s No ocb(%lx) on the queue\n",
1691#else
1692 "%s:%s No ocb(%x) on the queue\n",
1693#endif
1694 __func__,sdev->bustgtlun,
1695 ntohl(sbp_status->orb_lo));
1696 }
1697 break;
1698 case 2:
1699 /* unsolicit */
1700 device_printf(sdev->target->sbp->fd.dev,
1701 "%s:%s unsolicit status received\n",
1702 __func__, sdev->bustgtlun);
1703 break;
1704 default:
1705 device_printf(sdev->target->sbp->fd.dev,
1706 "%s:%s unknown sbp_status->src\n",
1707 __func__, sdev->bustgtlun);
1708 }
1709
1710 status_valid0 = (sbp_status->src < 2
1711 && sbp_status->resp == ORB_RES_CMPL
1712 && sbp_status->dead == 0);
1713 status_valid = (status_valid0 && sbp_status->status == 0);
1714
1715 if (!status_valid0 || debug > 2){
1716 int status;
1717SBP_DEBUG(0)
1718 device_printf(sdev->target->sbp->fd.dev,
1719 "%s:%s ORB status src:%x resp:%x dead:%x"
1720#if defined(__DragonFly__) || __FreeBSD_version < 500000
1721 " len:%x stat:%x orb:%x%08lx\n",
1722#else
1723 " len:%x stat:%x orb:%x%08x\n",
1724#endif
1725 __func__, sdev->bustgtlun,
1726 sbp_status->src, sbp_status->resp, sbp_status->dead,
1727 sbp_status->len, sbp_status->status,
1728 ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
1729END_DEBUG
1730 device_printf(sdev->target->sbp->fd.dev,
1731 "%s\n", sdev->bustgtlun);
1732 status = sbp_status->status;
1733 switch(sbp_status->resp) {
1734 case 0:
1735 if (status > MAX_ORB_STATUS0)
1736 printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
1737 else
1738 printf("%s\n", orb_status0[status]);
1739 break;
1740 case 1:
1741 printf("Obj: %s, Error: %s\n",
1742 orb_status1_object[(status>>6) & 3],
1743 orb_status1_serial_bus_error[status & 0xf]);
1744 break;
1745 case 2:
1746 printf("Illegal request\n");
1747 break;
1748 case 3:
1749 printf("Vendor dependent\n");
1750 break;
1751 default:
1752 printf("unknown respose code %d\n", sbp_status->resp);
1753 }
1754 }
1755
1756 /* we have to reset the fetch agent if it's dead */
1757 if (sbp_status->dead) {
1758 if (sdev->path) {
1799 SBP_LOCK(sbp);
1800 xpt_freeze_devq(sdev->path, 1);
1801 sdev->freeze ++;
1759 xpt_freeze_devq(sdev->path, 1);
1760 sdev->freeze ++;
1802 SBP_UNLOCK(sbp);
1803 }
1804 reset_agent = 1;
1805 }
1806
1807 if (ocb == NULL)
1808 goto done;
1809
1810 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
1811 case ORB_FMT_NOP:
1812 break;
1813 case ORB_FMT_VED:
1814 break;
1815 case ORB_FMT_STD:
1816 switch(ocb->flags) {
1817 case OCB_ACT_MGM:
1818 orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
1819 reset_agent = 0;
1820 switch(orb_fun) {
1821 case ORB_FUN_LGI:
1822 fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD);
1823 login_res = sdev->login;
1824 login_res->len = ntohs(login_res->len);
1825 login_res->id = ntohs(login_res->id);
1826 login_res->cmd_hi = ntohs(login_res->cmd_hi);
1827 login_res->cmd_lo = ntohl(login_res->cmd_lo);
1828 if (status_valid) {
1829SBP_DEBUG(0)
1830 device_printf(sdev->target->sbp->fd.dev,
1831 "%s:%s login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n",
1832 __func__, sdev->bustgtlun,
1833 login_res->len, login_res->id,
1834 login_res->cmd_hi, login_res->cmd_lo,
1835 ntohs(login_res->recon_hold));
1836END_DEBUG
1837 sbp_busy_timeout(sdev);
1838 } else {
1839 /* forgot logout? */
1840 device_printf(sdev->target->sbp->fd.dev,
1841 "%s:%s login failed\n",
1842 __func__, sdev->bustgtlun);
1843 sdev->status = SBP_DEV_RESET;
1844 }
1845 break;
1846 case ORB_FUN_RCN:
1847 login_res = sdev->login;
1848 if (status_valid) {
1849SBP_DEBUG(0)
1850 device_printf(sdev->target->sbp->fd.dev,
1851 "%s:%s reconnect: len %d, ID %d, cmd %08x%08x\n",
1852 __func__, sdev->bustgtlun,
1853 login_res->len, login_res->id,
1854 login_res->cmd_hi, login_res->cmd_lo);
1855END_DEBUG
1856 if (sdev->status == SBP_DEV_ATTACHED)
1857 sbp_scan_dev(sdev);
1858 else
1859 sbp_agent_reset(sdev);
1860 } else {
1861 /* reconnection hold time exceed? */
1862SBP_DEBUG(0)
1863 device_printf(sdev->target->sbp->fd.dev,
1864 "%s:%s reconnect failed\n",
1865 __func__, sdev->bustgtlun);
1866END_DEBUG
1867 sbp_login(sdev);
1868 }
1869 break;
1870 case ORB_FUN_LGO:
1871 sdev->status = SBP_DEV_RESET;
1872 break;
1873 case ORB_FUN_RST:
1874 sbp_busy_timeout(sdev);
1875 break;
1876 case ORB_FUN_LUR:
1877 case ORB_FUN_ATA:
1878 case ORB_FUN_ATS:
1879 sbp_agent_reset(sdev);
1880 break;
1881 default:
1882 device_printf(sdev->target->sbp->fd.dev,
1883 "%s:%s unknown function %d\n",
1884 __func__, sdev->bustgtlun, orb_fun);
1885 break;
1886 }
1887 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
1888 break;
1889 case OCB_ACT_CMD:
1890 sdev->timeout = 0;
1891 if(ocb->ccb != NULL){
1892 union ccb *ccb;
1893
1894 ccb = ocb->ccb;
1895 if(sbp_status->len > 1){
1896 sbp_scsi_status(sbp_status, ocb);
1897 }else{
1898 if(sbp_status->resp != ORB_RES_CMPL){
1899 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1900 }else{
1901 ccb->ccb_h.status = CAM_REQ_CMP;
1902 }
1903 }
1904 /* fix up inq data */
1905 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1906 sbp_fix_inq_data(ocb);
1761 }
1762 reset_agent = 1;
1763 }
1764
1765 if (ocb == NULL)
1766 goto done;
1767
1768 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
1769 case ORB_FMT_NOP:
1770 break;
1771 case ORB_FMT_VED:
1772 break;
1773 case ORB_FMT_STD:
1774 switch(ocb->flags) {
1775 case OCB_ACT_MGM:
1776 orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
1777 reset_agent = 0;
1778 switch(orb_fun) {
1779 case ORB_FUN_LGI:
1780 fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD);
1781 login_res = sdev->login;
1782 login_res->len = ntohs(login_res->len);
1783 login_res->id = ntohs(login_res->id);
1784 login_res->cmd_hi = ntohs(login_res->cmd_hi);
1785 login_res->cmd_lo = ntohl(login_res->cmd_lo);
1786 if (status_valid) {
1787SBP_DEBUG(0)
1788 device_printf(sdev->target->sbp->fd.dev,
1789 "%s:%s login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n",
1790 __func__, sdev->bustgtlun,
1791 login_res->len, login_res->id,
1792 login_res->cmd_hi, login_res->cmd_lo,
1793 ntohs(login_res->recon_hold));
1794END_DEBUG
1795 sbp_busy_timeout(sdev);
1796 } else {
1797 /* forgot logout? */
1798 device_printf(sdev->target->sbp->fd.dev,
1799 "%s:%s login failed\n",
1800 __func__, sdev->bustgtlun);
1801 sdev->status = SBP_DEV_RESET;
1802 }
1803 break;
1804 case ORB_FUN_RCN:
1805 login_res = sdev->login;
1806 if (status_valid) {
1807SBP_DEBUG(0)
1808 device_printf(sdev->target->sbp->fd.dev,
1809 "%s:%s reconnect: len %d, ID %d, cmd %08x%08x\n",
1810 __func__, sdev->bustgtlun,
1811 login_res->len, login_res->id,
1812 login_res->cmd_hi, login_res->cmd_lo);
1813END_DEBUG
1814 if (sdev->status == SBP_DEV_ATTACHED)
1815 sbp_scan_dev(sdev);
1816 else
1817 sbp_agent_reset(sdev);
1818 } else {
1819 /* reconnection hold time exceed? */
1820SBP_DEBUG(0)
1821 device_printf(sdev->target->sbp->fd.dev,
1822 "%s:%s reconnect failed\n",
1823 __func__, sdev->bustgtlun);
1824END_DEBUG
1825 sbp_login(sdev);
1826 }
1827 break;
1828 case ORB_FUN_LGO:
1829 sdev->status = SBP_DEV_RESET;
1830 break;
1831 case ORB_FUN_RST:
1832 sbp_busy_timeout(sdev);
1833 break;
1834 case ORB_FUN_LUR:
1835 case ORB_FUN_ATA:
1836 case ORB_FUN_ATS:
1837 sbp_agent_reset(sdev);
1838 break;
1839 default:
1840 device_printf(sdev->target->sbp->fd.dev,
1841 "%s:%s unknown function %d\n",
1842 __func__, sdev->bustgtlun, orb_fun);
1843 break;
1844 }
1845 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
1846 break;
1847 case OCB_ACT_CMD:
1848 sdev->timeout = 0;
1849 if(ocb->ccb != NULL){
1850 union ccb *ccb;
1851
1852 ccb = ocb->ccb;
1853 if(sbp_status->len > 1){
1854 sbp_scsi_status(sbp_status, ocb);
1855 }else{
1856 if(sbp_status->resp != ORB_RES_CMPL){
1857 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1858 }else{
1859 ccb->ccb_h.status = CAM_REQ_CMP;
1860 }
1861 }
1862 /* fix up inq data */
1863 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1864 sbp_fix_inq_data(ocb);
1907 SBP_LOCK(sbp);
1908 xpt_done(ccb);
1865 xpt_done(ccb);
1909 SBP_UNLOCK(sbp);
1910 }
1911 break;
1912 default:
1913 break;
1914 }
1915 }
1916
1917 if (!use_doorbell)
1918 sbp_free_ocb(sdev, ocb);
1919done:
1920 if (reset_agent)
1921 sbp_agent_reset(sdev);
1922
1923done0:
1924 xfer->recv.pay_len = SBP_RECV_LEN;
1925/* The received packet is usually small enough to be stored within
1926 * the buffer. In that case, the controller return ack_complete and
1927 * no respose is necessary.
1928 *
1929 * XXX fwohci.c and firewire.c should inform event_code such as
1930 * ack_complete or ack_pending to upper driver.
1931 */
1932#if NEED_RESPONSE
1933 xfer->send.off = 0;
1934 sfp = (struct fw_pkt *)xfer->send.buf;
1935 sfp->mode.wres.dst = rfp->mode.wreqb.src;
1936 xfer->dst = sfp->mode.wres.dst;
1937 xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1938 xfer->hand = sbp_loginres_callback;
1939
1940 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1941 sfp->mode.wres.tcode = FWTCODE_WRES;
1942 sfp->mode.wres.rtcode = 0;
1943 sfp->mode.wres.pri = 0;
1944
1945 fw_asyreq(xfer->fc, -1, xfer);
1946#else
1947 /* recycle */
1866 }
1867 break;
1868 default:
1869 break;
1870 }
1871 }
1872
1873 if (!use_doorbell)
1874 sbp_free_ocb(sdev, ocb);
1875done:
1876 if (reset_agent)
1877 sbp_agent_reset(sdev);
1878
1879done0:
1880 xfer->recv.pay_len = SBP_RECV_LEN;
1881/* The received packet is usually small enough to be stored within
1882 * the buffer. In that case, the controller return ack_complete and
1883 * no respose is necessary.
1884 *
1885 * XXX fwohci.c and firewire.c should inform event_code such as
1886 * ack_complete or ack_pending to upper driver.
1887 */
1888#if NEED_RESPONSE
1889 xfer->send.off = 0;
1890 sfp = (struct fw_pkt *)xfer->send.buf;
1891 sfp->mode.wres.dst = rfp->mode.wreqb.src;
1892 xfer->dst = sfp->mode.wres.dst;
1893 xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1894 xfer->hand = sbp_loginres_callback;
1895
1896 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1897 sfp->mode.wres.tcode = FWTCODE_WRES;
1898 sfp->mode.wres.rtcode = 0;
1899 sfp->mode.wres.pri = 0;
1900
1901 fw_asyreq(xfer->fc, -1, xfer);
1902#else
1903 /* recycle */
1948 /* we don't need a lock here because bottom half is serialized */
1949 STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
1950#endif
1904 STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
1905#endif
1951
1952 return;
1953
1954}
1955
1956static void
1957sbp_recv(struct fw_xfer *xfer)
1958{
1906}
1907
1908static void
1909sbp_recv(struct fw_xfer *xfer)
1910{
1959 int s;
1911 struct sbp_softc *sbp;
1960
1912
1961 s = splcam();
1913 sbp = (struct sbp_softc *)xfer->sc;
1914 SBP_LOCK(sbp);
1962 sbp_recv1(xfer);
1915 sbp_recv1(xfer);
1963 splx(s);
1916 SBP_UNLOCK(sbp);
1964}
1965/*
1966 * sbp_attach()
1967 */
1968static int
1969sbp_attach(device_t dev)
1970{
1971 struct sbp_softc *sbp;
1972 struct cam_devq *devq;
1973 struct firewire_comm *fc;
1917}
1918/*
1919 * sbp_attach()
1920 */
1921static int
1922sbp_attach(device_t dev)
1923{
1924 struct sbp_softc *sbp;
1925 struct cam_devq *devq;
1926 struct firewire_comm *fc;
1974 int i, s, error;
1927 int i, error;
1975
1976 if (DFLTPHYS > SBP_MAXPHYS)
1977 device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than "
1978 "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
1979 SBP_MAXPHYS / 1024);
1980
1981 if (!firewire_phydma_enable)
1982 device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 "
1983 "for SBP over FireWire.\n");
1984SBP_DEBUG(0)
1985 printf("sbp_attach (cold=%d)\n", cold);
1986END_DEBUG
1987
1988 if (cold)
1989 sbp_cold ++;
1928
1929 if (DFLTPHYS > SBP_MAXPHYS)
1930 device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than "
1931 "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
1932 SBP_MAXPHYS / 1024);
1933
1934 if (!firewire_phydma_enable)
1935 device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 "
1936 "for SBP over FireWire.\n");
1937SBP_DEBUG(0)
1938 printf("sbp_attach (cold=%d)\n", cold);
1939END_DEBUG
1940
1941 if (cold)
1942 sbp_cold ++;
1990 sbp = ((struct sbp_softc *)device_get_softc(dev));
1991 bzero(sbp, sizeof(struct sbp_softc));
1943 sbp = device_get_softc(dev);
1992 sbp->fd.dev = dev;
1993 sbp->fd.fc = fc = device_get_ivars(dev);
1994 mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
1995
1996 if (max_speed < 0)
1997 max_speed = fc->speed;
1998
1999 error = bus_dma_tag_create(/*parent*/fc->dmat,
2000 /* XXX shoud be 4 for sane backend? */
2001 /*alignment*/1,
2002 /*boundary*/0,
2003 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
2004 /*highaddr*/BUS_SPACE_MAXADDR,
2005 /*filter*/NULL, /*filterarg*/NULL,
2006 /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
2007 /*maxsegsz*/SBP_SEG_MAX,
2008 /*flags*/BUS_DMA_ALLOCNOW,
2009#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
2010 /*lockfunc*/busdma_lock_mutex,
2011 /*lockarg*/&sbp->mtx,
2012#endif
2013 &sbp->dmat);
2014 if (error != 0) {
2015 printf("sbp_attach: Could not allocate DMA tag "
2016 "- error %d\n", error);
2017 return (ENOMEM);
2018 }
2019
2020 devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
2021 if (devq == NULL)
2022 return (ENXIO);
2023
2024 for( i = 0 ; i < SBP_NUM_TARGETS ; i++){
2025 sbp->targets[i].fwdev = NULL;
2026 sbp->targets[i].luns = NULL;
2027 }
2028
2029 sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp,
2030 device_get_unit(dev),
2031 &sbp->mtx,
2032 /*untagged*/ 1,
2033 /*tagged*/ SBP_QUEUE_LEN - 1,
2034 devq);
2035
2036 if (sbp->sim == NULL) {
2037 cam_simq_free(devq);
2038 return (ENXIO);
2039 }
2040
2041 SBP_LOCK(sbp);
2042 if (xpt_bus_register(sbp->sim, dev, /*bus*/0) != CAM_SUCCESS)
2043 goto fail;
2044
2045 if (xpt_create_path(&sbp->path, NULL, cam_sim_path(sbp->sim),
2046 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2047 xpt_bus_deregister(cam_sim_path(sbp->sim));
2048 goto fail;
2049 }
2050 SBP_UNLOCK(sbp);
2051
2052 /* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */
2053 sbp->fwb.start = ((u_int64_t)SBP_BIND_HI << 32) | SBP_DEV2ADDR(0, 0);
2054 sbp->fwb.end = sbp->fwb.start + 0xffff;
2055 /* pre-allocate xfer */
2056 STAILQ_INIT(&sbp->fwb.xferlist);
2057 fw_xferlist_add(&sbp->fwb.xferlist, M_SBP,
2058 /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2,
2059 fc, (void *)sbp, sbp_recv);
2060
2061 fw_bindadd(fc, &sbp->fwb);
2062
2063 sbp->fd.post_busreset = sbp_post_busreset;
2064 sbp->fd.post_explore = sbp_post_explore;
2065
2066 if (fc->status != -1) {
1944 sbp->fd.dev = dev;
1945 sbp->fd.fc = fc = device_get_ivars(dev);
1946 mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
1947
1948 if (max_speed < 0)
1949 max_speed = fc->speed;
1950
1951 error = bus_dma_tag_create(/*parent*/fc->dmat,
1952 /* XXX shoud be 4 for sane backend? */
1953 /*alignment*/1,
1954 /*boundary*/0,
1955 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1956 /*highaddr*/BUS_SPACE_MAXADDR,
1957 /*filter*/NULL, /*filterarg*/NULL,
1958 /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
1959 /*maxsegsz*/SBP_SEG_MAX,
1960 /*flags*/BUS_DMA_ALLOCNOW,
1961#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
1962 /*lockfunc*/busdma_lock_mutex,
1963 /*lockarg*/&sbp->mtx,
1964#endif
1965 &sbp->dmat);
1966 if (error != 0) {
1967 printf("sbp_attach: Could not allocate DMA tag "
1968 "- error %d\n", error);
1969 return (ENOMEM);
1970 }
1971
1972 devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
1973 if (devq == NULL)
1974 return (ENXIO);
1975
1976 for( i = 0 ; i < SBP_NUM_TARGETS ; i++){
1977 sbp->targets[i].fwdev = NULL;
1978 sbp->targets[i].luns = NULL;
1979 }
1980
1981 sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp,
1982 device_get_unit(dev),
1983 &sbp->mtx,
1984 /*untagged*/ 1,
1985 /*tagged*/ SBP_QUEUE_LEN - 1,
1986 devq);
1987
1988 if (sbp->sim == NULL) {
1989 cam_simq_free(devq);
1990 return (ENXIO);
1991 }
1992
1993 SBP_LOCK(sbp);
1994 if (xpt_bus_register(sbp->sim, dev, /*bus*/0) != CAM_SUCCESS)
1995 goto fail;
1996
1997 if (xpt_create_path(&sbp->path, NULL, cam_sim_path(sbp->sim),
1998 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1999 xpt_bus_deregister(cam_sim_path(sbp->sim));
2000 goto fail;
2001 }
2002 SBP_UNLOCK(sbp);
2003
2004 /* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */
2005 sbp->fwb.start = ((u_int64_t)SBP_BIND_HI << 32) | SBP_DEV2ADDR(0, 0);
2006 sbp->fwb.end = sbp->fwb.start + 0xffff;
2007 /* pre-allocate xfer */
2008 STAILQ_INIT(&sbp->fwb.xferlist);
2009 fw_xferlist_add(&sbp->fwb.xferlist, M_SBP,
2010 /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2,
2011 fc, (void *)sbp, sbp_recv);
2012
2013 fw_bindadd(fc, &sbp->fwb);
2014
2015 sbp->fd.post_busreset = sbp_post_busreset;
2016 sbp->fd.post_explore = sbp_post_explore;
2017
2018 if (fc->status != -1) {
2067 s = splfw();
2068 sbp_post_busreset((void *)sbp);
2069 sbp_post_explore((void *)sbp);
2019 sbp_post_busreset((void *)sbp);
2020 sbp_post_explore((void *)sbp);
2070 splx(s);
2071 }
2072 SBP_LOCK(sbp);
2073 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
2074 SBP_UNLOCK(sbp);
2075
2076 return (0);
2077fail:
2078 SBP_UNLOCK(sbp);
2079 cam_sim_free(sbp->sim, /*free_devq*/TRUE);
2080 return (ENXIO);
2081}
2082
2083static int
2084sbp_logout_all(struct sbp_softc *sbp)
2085{
2086 struct sbp_target *target;
2087 struct sbp_dev *sdev;
2088 int i, j;
2089
2090SBP_DEBUG(0)
2091 printf("sbp_logout_all\n");
2092END_DEBUG
2021 }
2022 SBP_LOCK(sbp);
2023 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
2024 SBP_UNLOCK(sbp);
2025
2026 return (0);
2027fail:
2028 SBP_UNLOCK(sbp);
2029 cam_sim_free(sbp->sim, /*free_devq*/TRUE);
2030 return (ENXIO);
2031}
2032
2033static int
2034sbp_logout_all(struct sbp_softc *sbp)
2035{
2036 struct sbp_target *target;
2037 struct sbp_dev *sdev;
2038 int i, j;
2039
2040SBP_DEBUG(0)
2041 printf("sbp_logout_all\n");
2042END_DEBUG
2043 SBP_LOCK_ASSERT(sbp);
2093 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
2094 target = &sbp->targets[i];
2095 if (target->luns == NULL)
2096 continue;
2097 for (j = 0; j < target->num_lun; j++) {
2098 sdev = target->luns[j];
2099 if (sdev == NULL)
2100 continue;
2101 callout_stop(&sdev->login_callout);
2102 if (sdev->status >= SBP_DEV_TOATTACH &&
2103 sdev->status <= SBP_DEV_ATTACHED)
2104 sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
2105 }
2106 }
2107
2108 return 0;
2109}
2110
2111static int
2112sbp_shutdown(device_t dev)
2113{
2114 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2115
2044 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
2045 target = &sbp->targets[i];
2046 if (target->luns == NULL)
2047 continue;
2048 for (j = 0; j < target->num_lun; j++) {
2049 sdev = target->luns[j];
2050 if (sdev == NULL)
2051 continue;
2052 callout_stop(&sdev->login_callout);
2053 if (sdev->status >= SBP_DEV_TOATTACH &&
2054 sdev->status <= SBP_DEV_ATTACHED)
2055 sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
2056 }
2057 }
2058
2059 return 0;
2060}
2061
2062static int
2063sbp_shutdown(device_t dev)
2064{
2065 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2066
2067 SBP_LOCK(sbp);
2116 sbp_logout_all(sbp);
2068 sbp_logout_all(sbp);
2069 SBP_UNLOCK(sbp);
2117 return (0);
2118}
2119
2120static void
2121sbp_free_sdev(struct sbp_dev *sdev)
2122{
2070 return (0);
2071}
2072
2073static void
2074sbp_free_sdev(struct sbp_dev *sdev)
2075{
2076 struct sbp_softc *sbp;
2123 int i;
2124
2125 if (sdev == NULL)
2126 return;
2077 int i;
2078
2079 if (sdev == NULL)
2080 return;
2127 for (i = 0; i < SBP_QUEUE_LEN; i++)
2128 bus_dmamap_destroy(sdev->target->sbp->dmat,
2129 sdev->ocb[i].dmamap);
2130 fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
2081 sbp = sdev->target->sbp;
2082 SBP_UNLOCK(sbp);
2083 callout_drain(&sdev->login_callout);
2084 for (i = 0; i < SBP_QUEUE_LEN; i++) {
2085 callout_drain(&sdev->ocb[i].timer);
2086 bus_dmamap_destroy(sbp->dmat, sdev->ocb[i].dmamap);
2087 }
2088 fwdma_free(sbp->fd.fc, &sdev->dma);
2131 free(sdev, M_SBP);
2089 free(sdev, M_SBP);
2132 sdev = NULL;
2090 SBP_LOCK(sbp);
2133}
2134
2135static void
2136sbp_free_target(struct sbp_target *target)
2137{
2138 struct sbp_softc *sbp;
2139 struct fw_xfer *xfer, *next;
2140 int i;
2141
2142 if (target->luns == NULL)
2143 return;
2091}
2092
2093static void
2094sbp_free_target(struct sbp_target *target)
2095{
2096 struct sbp_softc *sbp;
2097 struct fw_xfer *xfer, *next;
2098 int i;
2099
2100 if (target->luns == NULL)
2101 return;
2144 callout_stop(&target->mgm_ocb_timeout);
2145 sbp = target->sbp;
2102 sbp = target->sbp;
2103 SBP_LOCK_ASSERT(sbp);
2104 SBP_UNLOCK(sbp);
2105 callout_drain(&target->mgm_ocb_timeout);
2106 callout_drain(&target->scan_callout);
2107 SBP_LOCK(sbp);
2146 for (i = 0; i < target->num_lun; i++)
2147 sbp_free_sdev(target->luns[i]);
2148
2108 for (i = 0; i < target->num_lun; i++)
2109 sbp_free_sdev(target->luns[i]);
2110
2149 for (xfer = STAILQ_FIRST(&target->xferlist);
2150 xfer != NULL; xfer = next) {
2151 next = STAILQ_NEXT(xfer, link);
2111 STAILQ_FOREACH_SAFE(xfer, &target->xferlist, link, next) {
2152 fw_xfer_free_buf(xfer);
2153 }
2154 STAILQ_INIT(&target->xferlist);
2155 free(target->luns, M_SBP);
2156 target->num_lun = 0;
2157 target->luns = NULL;
2158 target->fwdev = NULL;
2159}
2160
2161static int
2162sbp_detach(device_t dev)
2163{
2164 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2165 struct firewire_comm *fc = sbp->fd.fc;
2166 int i;
2167
2168SBP_DEBUG(0)
2169 printf("sbp_detach\n");
2170END_DEBUG
2171
2112 fw_xfer_free_buf(xfer);
2113 }
2114 STAILQ_INIT(&target->xferlist);
2115 free(target->luns, M_SBP);
2116 target->num_lun = 0;
2117 target->luns = NULL;
2118 target->fwdev = NULL;
2119}
2120
2121static int
2122sbp_detach(device_t dev)
2123{
2124 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2125 struct firewire_comm *fc = sbp->fd.fc;
2126 int i;
2127
2128SBP_DEBUG(0)
2129 printf("sbp_detach\n");
2130END_DEBUG
2131
2132 SBP_LOCK(sbp);
2172 for (i = 0; i < SBP_NUM_TARGETS; i ++)
2173 sbp_cam_detach_target(&sbp->targets[i]);
2174
2133 for (i = 0; i < SBP_NUM_TARGETS; i ++)
2134 sbp_cam_detach_target(&sbp->targets[i]);
2135
2175 SBP_LOCK(sbp);
2176 xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
2177 xpt_free_path(sbp->path);
2178 xpt_bus_deregister(cam_sim_path(sbp->sim));
2179 cam_sim_free(sbp->sim, /*free_devq*/ TRUE);
2136 xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
2137 xpt_free_path(sbp->path);
2138 xpt_bus_deregister(cam_sim_path(sbp->sim));
2139 cam_sim_free(sbp->sim, /*free_devq*/ TRUE);
2180 SBP_UNLOCK(sbp);
2181
2182 sbp_logout_all(sbp);
2140
2141 sbp_logout_all(sbp);
2142 SBP_UNLOCK(sbp);
2183
2184 /* XXX wait for logout completion */
2185 pause("sbpdtc", hz/2);
2186
2143
2144 /* XXX wait for logout completion */
2145 pause("sbpdtc", hz/2);
2146
2147 SBP_LOCK(sbp);
2187 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++)
2188 sbp_free_target(&sbp->targets[i]);
2148 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++)
2149 sbp_free_target(&sbp->targets[i]);
2150 SBP_UNLOCK(sbp);
2189
2190 fw_bindremove(fc, &sbp->fwb);
2191 fw_xferlist_remove(&sbp->fwb.xferlist);
2192
2193 bus_dma_tag_destroy(sbp->dmat);
2194 mtx_destroy(&sbp->mtx);
2195
2196 return (0);
2197}
2198
2199static void
2200sbp_cam_detach_sdev(struct sbp_dev *sdev)
2201{
2202 if (sdev == NULL)
2203 return;
2204 if (sdev->status == SBP_DEV_DEAD)
2205 return;
2206 if (sdev->status == SBP_DEV_RESET)
2207 return;
2151
2152 fw_bindremove(fc, &sbp->fwb);
2153 fw_xferlist_remove(&sbp->fwb.xferlist);
2154
2155 bus_dma_tag_destroy(sbp->dmat);
2156 mtx_destroy(&sbp->mtx);
2157
2158 return (0);
2159}
2160
2161static void
2162sbp_cam_detach_sdev(struct sbp_dev *sdev)
2163{
2164 if (sdev == NULL)
2165 return;
2166 if (sdev->status == SBP_DEV_DEAD)
2167 return;
2168 if (sdev->status == SBP_DEV_RESET)
2169 return;
2170 SBP_LOCK_ASSERT(sdev->target->sbp);
2208 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
2209 if (sdev->path) {
2171 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
2172 if (sdev->path) {
2210 SBP_LOCK(sdev->target->sbp);
2211 xpt_release_devq(sdev->path,
2212 sdev->freeze, TRUE);
2213 sdev->freeze = 0;
2214 xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
2215 xpt_free_path(sdev->path);
2216 sdev->path = NULL;
2173 xpt_release_devq(sdev->path,
2174 sdev->freeze, TRUE);
2175 sdev->freeze = 0;
2176 xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
2177 xpt_free_path(sdev->path);
2178 sdev->path = NULL;
2217 SBP_UNLOCK(sdev->target->sbp);
2218 }
2219}
2220
2221static void
2222sbp_cam_detach_target(struct sbp_target *target)
2223{
2224 int i;
2225
2179 }
2180}
2181
2182static void
2183sbp_cam_detach_target(struct sbp_target *target)
2184{
2185 int i;
2186
2187 SBP_LOCK_ASSERT(target->sbp);
2226 if (target->luns != NULL) {
2227SBP_DEBUG(0)
2228 printf("sbp_detach_target %d\n", target->target_id);
2229END_DEBUG
2230 callout_stop(&target->scan_callout);
2231 for (i = 0; i < target->num_lun; i++)
2232 sbp_cam_detach_sdev(target->luns[i]);
2233 }
2234}
2235
2236static void
2237sbp_target_reset(struct sbp_dev *sdev, int method)
2238{
2239 int i;
2240 struct sbp_target *target = sdev->target;
2241 struct sbp_dev *tsdev;
2242
2188 if (target->luns != NULL) {
2189SBP_DEBUG(0)
2190 printf("sbp_detach_target %d\n", target->target_id);
2191END_DEBUG
2192 callout_stop(&target->scan_callout);
2193 for (i = 0; i < target->num_lun; i++)
2194 sbp_cam_detach_sdev(target->luns[i]);
2195 }
2196}
2197
2198static void
2199sbp_target_reset(struct sbp_dev *sdev, int method)
2200{
2201 int i;
2202 struct sbp_target *target = sdev->target;
2203 struct sbp_dev *tsdev;
2204
2205 SBP_LOCK_ASSERT(target->sbp);
2243 for (i = 0; i < target->num_lun; i++) {
2244 tsdev = target->luns[i];
2245 if (tsdev == NULL)
2246 continue;
2247 if (tsdev->status == SBP_DEV_DEAD)
2248 continue;
2249 if (tsdev->status == SBP_DEV_RESET)
2250 continue;
2206 for (i = 0; i < target->num_lun; i++) {
2207 tsdev = target->luns[i];
2208 if (tsdev == NULL)
2209 continue;
2210 if (tsdev->status == SBP_DEV_DEAD)
2211 continue;
2212 if (tsdev->status == SBP_DEV_RESET)
2213 continue;
2251 SBP_LOCK(target->sbp);
2252 xpt_freeze_devq(tsdev->path, 1);
2253 tsdev->freeze ++;
2214 xpt_freeze_devq(tsdev->path, 1);
2215 tsdev->freeze ++;
2254 SBP_UNLOCK(target->sbp);
2255 sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT);
2256 if (method == 2)
2257 tsdev->status = SBP_DEV_LOGIN;
2258 }
2259 switch(method) {
2260 case 1:
2261 printf("target reset\n");
2262 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);
2263 break;
2264 case 2:
2265 printf("reset start\n");
2266 sbp_reset_start(sdev);
2267 break;
2268 }
2269
2270}
2271
2272static void
2273sbp_mgm_timeout(void *arg)
2274{
2275 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2276 struct sbp_dev *sdev = ocb->sdev;
2277 struct sbp_target *target = sdev->target;
2278
2216 sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT);
2217 if (method == 2)
2218 tsdev->status = SBP_DEV_LOGIN;
2219 }
2220 switch(method) {
2221 case 1:
2222 printf("target reset\n");
2223 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);
2224 break;
2225 case 2:
2226 printf("reset start\n");
2227 sbp_reset_start(sdev);
2228 break;
2229 }
2230
2231}
2232
2233static void
2234sbp_mgm_timeout(void *arg)
2235{
2236 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2237 struct sbp_dev *sdev = ocb->sdev;
2238 struct sbp_target *target = sdev->target;
2239
2240 SBP_LOCK_ASSERT(target->sbp);
2279 device_printf(sdev->target->sbp->fd.dev,
2280 "%s:%s request timeout(mgm orb:0x%08x)\n",
2281 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2282 target->mgm_ocb_cur = NULL;
2283 sbp_free_ocb(sdev, ocb);
2284#if 0
2285 /* XXX */
2286 printf("run next request\n");
2287 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
2288#endif
2289 device_printf(sdev->target->sbp->fd.dev,
2290 "%s:%s reset start\n",
2291 __func__, sdev->bustgtlun);
2292 sbp_reset_start(sdev);
2293}
2294
2295static void
2296sbp_timeout(void *arg)
2297{
2298 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2299 struct sbp_dev *sdev = ocb->sdev;
2300
2301 device_printf(sdev->target->sbp->fd.dev,
2302 "%s:%s request timeout(cmd orb:0x%08x) ... ",
2303 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2304
2241 device_printf(sdev->target->sbp->fd.dev,
2242 "%s:%s request timeout(mgm orb:0x%08x)\n",
2243 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2244 target->mgm_ocb_cur = NULL;
2245 sbp_free_ocb(sdev, ocb);
2246#if 0
2247 /* XXX */
2248 printf("run next request\n");
2249 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
2250#endif
2251 device_printf(sdev->target->sbp->fd.dev,
2252 "%s:%s reset start\n",
2253 __func__, sdev->bustgtlun);
2254 sbp_reset_start(sdev);
2255}
2256
2257static void
2258sbp_timeout(void *arg)
2259{
2260 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2261 struct sbp_dev *sdev = ocb->sdev;
2262
2263 device_printf(sdev->target->sbp->fd.dev,
2264 "%s:%s request timeout(cmd orb:0x%08x) ... ",
2265 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2266
2267 SBP_LOCK_ASSERT(sdev->target->sbp);
2305 sdev->timeout ++;
2306 switch(sdev->timeout) {
2307 case 1:
2308 printf("agent reset\n");
2268 sdev->timeout ++;
2269 switch(sdev->timeout) {
2270 case 1:
2271 printf("agent reset\n");
2309 SBP_LOCK(sdev->target->sbp);
2310 xpt_freeze_devq(sdev->path, 1);
2311 sdev->freeze ++;
2272 xpt_freeze_devq(sdev->path, 1);
2273 sdev->freeze ++;
2312 SBP_UNLOCK(sdev->target->sbp);
2313 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
2314 sbp_agent_reset(sdev);
2315 break;
2316 case 2:
2317 case 3:
2318 sbp_target_reset(sdev, sdev->timeout - 1);
2319 break;
2320#if 0
2321 default:
2322 /* XXX give up */
2323 sbp_cam_detach_target(target);
2324 if (target->luns != NULL)
2325 free(target->luns, M_SBP);
2326 target->num_lun = 0;
2327 target->luns = NULL;
2328 target->fwdev = NULL;
2329#endif
2330 }
2331}
2332
2333static void
2274 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
2275 sbp_agent_reset(sdev);
2276 break;
2277 case 2:
2278 case 3:
2279 sbp_target_reset(sdev, sdev->timeout - 1);
2280 break;
2281#if 0
2282 default:
2283 /* XXX give up */
2284 sbp_cam_detach_target(target);
2285 if (target->luns != NULL)
2286 free(target->luns, M_SBP);
2287 target->num_lun = 0;
2288 target->luns = NULL;
2289 target->fwdev = NULL;
2290#endif
2291 }
2292}
2293
2294static void
2334sbp_action1(struct cam_sim *sim, union ccb *ccb)
2295sbp_action(struct cam_sim *sim, union ccb *ccb)
2335{
2336
2337 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
2338 struct sbp_target *target = NULL;
2339 struct sbp_dev *sdev = NULL;
2340
2296{
2297
2298 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
2299 struct sbp_target *target = NULL;
2300 struct sbp_dev *sdev = NULL;
2301
2302 if (sbp != NULL)
2303 SBP_LOCK_ASSERT(sbp);
2341 /* target:lun -> sdev mapping */
2342 if (sbp != NULL
2343 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
2344 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
2345 target = &sbp->targets[ccb->ccb_h.target_id];
2346 if (target->fwdev != NULL
2347 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
2348 && ccb->ccb_h.target_lun < target->num_lun) {
2349 sdev = target->luns[ccb->ccb_h.target_lun];
2350 if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
2351 sdev->status != SBP_DEV_PROBE)
2352 sdev = NULL;
2353 }
2354 }
2355
2356SBP_DEBUG(1)
2357 if (sdev == NULL)
2358 printf("invalid target %d lun %jx\n",
2359 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2360END_DEBUG
2361
2362 switch (ccb->ccb_h.func_code) {
2363 case XPT_SCSI_IO:
2364 case XPT_RESET_DEV:
2365 case XPT_GET_TRAN_SETTINGS:
2366 case XPT_SET_TRAN_SETTINGS:
2367 case XPT_CALC_GEOMETRY:
2368 if (sdev == NULL) {
2369SBP_DEBUG(1)
2370 printf("%s:%d:%jx:func_code 0x%04x: "
2371 "Invalid target (target needed)\n",
2372 device_get_nameunit(sbp->fd.dev),
2373 ccb->ccb_h.target_id,
2374 (uintmax_t)ccb->ccb_h.target_lun,
2375 ccb->ccb_h.func_code);
2376END_DEBUG
2377
2378 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2379 xpt_done(ccb);
2380 return;
2381 }
2382 break;
2383 case XPT_PATH_INQ:
2384 case XPT_NOOP:
2385 /* The opcodes sometimes aimed at a target (sc is valid),
2386 * sometimes aimed at the SIM (sc is invalid and target is
2387 * CAM_TARGET_WILDCARD)
2388 */
2389 if (sbp == NULL &&
2390 ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
2391SBP_DEBUG(0)
2392 printf("%s:%d:%jx func_code 0x%04x: "
2393 "Invalid target (no wildcard)\n",
2394 device_get_nameunit(sbp->fd.dev),
2395 ccb->ccb_h.target_id,
2396 (uintmax_t)ccb->ccb_h.target_lun,
2397 ccb->ccb_h.func_code);
2398END_DEBUG
2399 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2400 xpt_done(ccb);
2401 return;
2402 }
2403 break;
2404 default:
2405 /* XXX Hm, we should check the input parameters */
2406 break;
2407 }
2408
2409 switch (ccb->ccb_h.func_code) {
2410 case XPT_SCSI_IO:
2411 {
2412 struct ccb_scsiio *csio;
2413 struct sbp_ocb *ocb;
2414 int speed;
2415 void *cdb;
2416
2417 csio = &ccb->csio;
2418 mtx_assert(sim->mtx, MA_OWNED);
2419
2420SBP_DEBUG(2)
2421 printf("%s:%d:%jx XPT_SCSI_IO: "
2422 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
2423 ", flags: 0x%02x, "
2424 "%db cmd/%db data/%db sense\n",
2425 device_get_nameunit(sbp->fd.dev),
2426 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun,
2427 csio->cdb_io.cdb_bytes[0],
2428 csio->cdb_io.cdb_bytes[1],
2429 csio->cdb_io.cdb_bytes[2],
2430 csio->cdb_io.cdb_bytes[3],
2431 csio->cdb_io.cdb_bytes[4],
2432 csio->cdb_io.cdb_bytes[5],
2433 csio->cdb_io.cdb_bytes[6],
2434 csio->cdb_io.cdb_bytes[7],
2435 csio->cdb_io.cdb_bytes[8],
2436 csio->cdb_io.cdb_bytes[9],
2437 ccb->ccb_h.flags & CAM_DIR_MASK,
2438 csio->cdb_len, csio->dxfer_len,
2439 csio->sense_len);
2440END_DEBUG
2441 if(sdev == NULL){
2442 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2443 xpt_done(ccb);
2444 return;
2445 }
2446#if 0
2447 /* if we are in probe stage, pass only probe commands */
2448 if (sdev->status == SBP_DEV_PROBE) {
2449 char *name;
2450 name = xpt_path_periph(ccb->ccb_h.path)->periph_name;
2451 printf("probe stage, periph name: %s\n", name);
2452 if (strcmp(name, "probe") != 0) {
2453 ccb->ccb_h.status = CAM_REQUEUE_REQ;
2454 xpt_done(ccb);
2455 return;
2456 }
2457 }
2458#endif
2459 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
2460 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2461 if (sdev->freeze == 0) {
2304 /* target:lun -> sdev mapping */
2305 if (sbp != NULL
2306 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
2307 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
2308 target = &sbp->targets[ccb->ccb_h.target_id];
2309 if (target->fwdev != NULL
2310 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
2311 && ccb->ccb_h.target_lun < target->num_lun) {
2312 sdev = target->luns[ccb->ccb_h.target_lun];
2313 if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
2314 sdev->status != SBP_DEV_PROBE)
2315 sdev = NULL;
2316 }
2317 }
2318
2319SBP_DEBUG(1)
2320 if (sdev == NULL)
2321 printf("invalid target %d lun %jx\n",
2322 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2323END_DEBUG
2324
2325 switch (ccb->ccb_h.func_code) {
2326 case XPT_SCSI_IO:
2327 case XPT_RESET_DEV:
2328 case XPT_GET_TRAN_SETTINGS:
2329 case XPT_SET_TRAN_SETTINGS:
2330 case XPT_CALC_GEOMETRY:
2331 if (sdev == NULL) {
2332SBP_DEBUG(1)
2333 printf("%s:%d:%jx:func_code 0x%04x: "
2334 "Invalid target (target needed)\n",
2335 device_get_nameunit(sbp->fd.dev),
2336 ccb->ccb_h.target_id,
2337 (uintmax_t)ccb->ccb_h.target_lun,
2338 ccb->ccb_h.func_code);
2339END_DEBUG
2340
2341 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2342 xpt_done(ccb);
2343 return;
2344 }
2345 break;
2346 case XPT_PATH_INQ:
2347 case XPT_NOOP:
2348 /* The opcodes sometimes aimed at a target (sc is valid),
2349 * sometimes aimed at the SIM (sc is invalid and target is
2350 * CAM_TARGET_WILDCARD)
2351 */
2352 if (sbp == NULL &&
2353 ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
2354SBP_DEBUG(0)
2355 printf("%s:%d:%jx func_code 0x%04x: "
2356 "Invalid target (no wildcard)\n",
2357 device_get_nameunit(sbp->fd.dev),
2358 ccb->ccb_h.target_id,
2359 (uintmax_t)ccb->ccb_h.target_lun,
2360 ccb->ccb_h.func_code);
2361END_DEBUG
2362 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2363 xpt_done(ccb);
2364 return;
2365 }
2366 break;
2367 default:
2368 /* XXX Hm, we should check the input parameters */
2369 break;
2370 }
2371
2372 switch (ccb->ccb_h.func_code) {
2373 case XPT_SCSI_IO:
2374 {
2375 struct ccb_scsiio *csio;
2376 struct sbp_ocb *ocb;
2377 int speed;
2378 void *cdb;
2379
2380 csio = &ccb->csio;
2381 mtx_assert(sim->mtx, MA_OWNED);
2382
2383SBP_DEBUG(2)
2384 printf("%s:%d:%jx XPT_SCSI_IO: "
2385 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
2386 ", flags: 0x%02x, "
2387 "%db cmd/%db data/%db sense\n",
2388 device_get_nameunit(sbp->fd.dev),
2389 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun,
2390 csio->cdb_io.cdb_bytes[0],
2391 csio->cdb_io.cdb_bytes[1],
2392 csio->cdb_io.cdb_bytes[2],
2393 csio->cdb_io.cdb_bytes[3],
2394 csio->cdb_io.cdb_bytes[4],
2395 csio->cdb_io.cdb_bytes[5],
2396 csio->cdb_io.cdb_bytes[6],
2397 csio->cdb_io.cdb_bytes[7],
2398 csio->cdb_io.cdb_bytes[8],
2399 csio->cdb_io.cdb_bytes[9],
2400 ccb->ccb_h.flags & CAM_DIR_MASK,
2401 csio->cdb_len, csio->dxfer_len,
2402 csio->sense_len);
2403END_DEBUG
2404 if(sdev == NULL){
2405 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2406 xpt_done(ccb);
2407 return;
2408 }
2409#if 0
2410 /* if we are in probe stage, pass only probe commands */
2411 if (sdev->status == SBP_DEV_PROBE) {
2412 char *name;
2413 name = xpt_path_periph(ccb->ccb_h.path)->periph_name;
2414 printf("probe stage, periph name: %s\n", name);
2415 if (strcmp(name, "probe") != 0) {
2416 ccb->ccb_h.status = CAM_REQUEUE_REQ;
2417 xpt_done(ccb);
2418 return;
2419 }
2420 }
2421#endif
2422 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
2423 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2424 if (sdev->freeze == 0) {
2462 SBP_LOCK(sdev->target->sbp);
2463 xpt_freeze_devq(sdev->path, 1);
2464 sdev->freeze ++;
2425 xpt_freeze_devq(sdev->path, 1);
2426 sdev->freeze ++;
2465 SBP_UNLOCK(sdev->target->sbp);
2466 }
2467 xpt_done(ccb);
2468 return;
2469 }
2470
2471 ocb->flags = OCB_ACT_CMD;
2472 ocb->sdev = sdev;
2473 ocb->ccb = ccb;
2474 ccb->ccb_h.ccb_sdev_ptr = sdev;
2475 ocb->orb[0] = htonl(1U << 31);
2476 ocb->orb[1] = 0;
2477 ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
2478 ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
2479 speed = min(target->fwdev->speed, max_speed);
2480 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
2481 | ORB_CMD_MAXP(speed + 7));
2482 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){
2483 ocb->orb[4] |= htonl(ORB_CMD_IN);
2484 }
2485
2486 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2487 cdb = (void *)csio->cdb_io.cdb_ptr;
2488 else
2489 cdb = (void *)&csio->cdb_io.cdb_bytes;
2490 bcopy(cdb, (void *)&ocb->orb[5], csio->cdb_len);
2491/*
2492printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
2493printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
2494*/
2495 if (ccb->csio.dxfer_len > 0) {
2496 int error;
2497
2498 error = bus_dmamap_load_ccb(/*dma tag*/sbp->dmat,
2499 /*dma map*/ocb->dmamap,
2500 ccb,
2501 sbp_execute_ocb,
2502 ocb,
2503 /*flags*/0);
2504 if (error)
2505 printf("sbp: bus_dmamap_load error %d\n", error);
2506 } else
2507 sbp_execute_ocb(ocb, NULL, 0, 0);
2508 break;
2509 }
2510 case XPT_CALC_GEOMETRY:
2511 {
2512 struct ccb_calc_geometry *ccg;
2513#if defined(__DragonFly__) || __FreeBSD_version < 501100
2514 uint32_t size_mb;
2515 uint32_t secs_per_cylinder;
2516 int extended = 1;
2517#endif
2518
2519 ccg = &ccb->ccg;
2520 if (ccg->block_size == 0) {
2427 }
2428 xpt_done(ccb);
2429 return;
2430 }
2431
2432 ocb->flags = OCB_ACT_CMD;
2433 ocb->sdev = sdev;
2434 ocb->ccb = ccb;
2435 ccb->ccb_h.ccb_sdev_ptr = sdev;
2436 ocb->orb[0] = htonl(1U << 31);
2437 ocb->orb[1] = 0;
2438 ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
2439 ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
2440 speed = min(target->fwdev->speed, max_speed);
2441 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
2442 | ORB_CMD_MAXP(speed + 7));
2443 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){
2444 ocb->orb[4] |= htonl(ORB_CMD_IN);
2445 }
2446
2447 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2448 cdb = (void *)csio->cdb_io.cdb_ptr;
2449 else
2450 cdb = (void *)&csio->cdb_io.cdb_bytes;
2451 bcopy(cdb, (void *)&ocb->orb[5], csio->cdb_len);
2452/*
2453printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
2454printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
2455*/
2456 if (ccb->csio.dxfer_len > 0) {
2457 int error;
2458
2459 error = bus_dmamap_load_ccb(/*dma tag*/sbp->dmat,
2460 /*dma map*/ocb->dmamap,
2461 ccb,
2462 sbp_execute_ocb,
2463 ocb,
2464 /*flags*/0);
2465 if (error)
2466 printf("sbp: bus_dmamap_load error %d\n", error);
2467 } else
2468 sbp_execute_ocb(ocb, NULL, 0, 0);
2469 break;
2470 }
2471 case XPT_CALC_GEOMETRY:
2472 {
2473 struct ccb_calc_geometry *ccg;
2474#if defined(__DragonFly__) || __FreeBSD_version < 501100
2475 uint32_t size_mb;
2476 uint32_t secs_per_cylinder;
2477 int extended = 1;
2478#endif
2479
2480 ccg = &ccb->ccg;
2481 if (ccg->block_size == 0) {
2521 printf("sbp_action1: block_size is 0.\n");
2482 printf("sbp_action: block_size is 0.\n");
2522 ccb->ccb_h.status = CAM_REQ_INVALID;
2523 xpt_done(ccb);
2524 break;
2525 }
2526SBP_DEBUG(1)
2527 printf("%s:%d:%d:%jx:XPT_CALC_GEOMETRY: "
2528#if defined(__DragonFly__) || __FreeBSD_version < 500000
2529 "Volume size = %d\n",
2530#else
2531 "Volume size = %jd\n",
2532#endif
2533 device_get_nameunit(sbp->fd.dev),
2534 cam_sim_path(sbp->sim),
2535 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun,
2536#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2537 (uintmax_t)
2538#endif
2539 ccg->volume_size);
2540END_DEBUG
2541
2542#if defined(__DragonFly__) || __FreeBSD_version < 501100
2543 size_mb = ccg->volume_size
2544 / ((1024L * 1024L) / ccg->block_size);
2545
2546 if (size_mb > 1024 && extended) {
2547 ccg->heads = 255;
2548 ccg->secs_per_track = 63;
2549 } else {
2550 ccg->heads = 64;
2551 ccg->secs_per_track = 32;
2552 }
2553 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2554 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2555 ccb->ccb_h.status = CAM_REQ_CMP;
2556#else
2557 cam_calc_geometry(ccg, /*extended*/1);
2558#endif
2559 xpt_done(ccb);
2560 break;
2561 }
2562 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
2563 {
2564
2565SBP_DEBUG(1)
2566 printf("%s:%d:XPT_RESET_BUS: \n",
2567 device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
2568END_DEBUG
2569
2570 ccb->ccb_h.status = CAM_REQ_INVALID;
2571 xpt_done(ccb);
2572 break;
2573 }
2574 case XPT_PATH_INQ: /* Path routing inquiry */
2575 {
2576 struct ccb_pathinq *cpi = &ccb->cpi;
2577
2578SBP_DEBUG(1)
2579 printf("%s:%d:%jx XPT_PATH_INQ:.\n",
2580 device_get_nameunit(sbp->fd.dev),
2581 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2582END_DEBUG
2583 cpi->version_num = 1; /* XXX??? */
2584 cpi->hba_inquiry = PI_TAG_ABLE;
2585 cpi->target_sprt = 0;
2586 cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
2587 cpi->hba_eng_cnt = 0;
2588 cpi->max_target = SBP_NUM_TARGETS - 1;
2589 cpi->max_lun = SBP_NUM_LUNS - 1;
2590 cpi->initiator_id = SBP_INITIATOR;
2591 cpi->bus_id = sim->bus_id;
2592 cpi->base_transfer_speed = 400 * 1000 / 8;
2593 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2594 strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
2595 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
2596 cpi->unit_number = sim->unit_number;
2597 cpi->transport = XPORT_SPI; /* XX should have a FireWire */
2598 cpi->transport_version = 2;
2599 cpi->protocol = PROTO_SCSI;
2600 cpi->protocol_version = SCSI_REV_2;
2601
2602 cpi->ccb_h.status = CAM_REQ_CMP;
2603 xpt_done(ccb);
2604 break;
2605 }
2606 case XPT_GET_TRAN_SETTINGS:
2607 {
2608 struct ccb_trans_settings *cts = &ccb->cts;
2609 struct ccb_trans_settings_scsi *scsi =
2610 &cts->proto_specific.scsi;
2611 struct ccb_trans_settings_spi *spi =
2612 &cts->xport_specific.spi;
2613
2614 cts->protocol = PROTO_SCSI;
2615 cts->protocol_version = SCSI_REV_2;
2616 cts->transport = XPORT_SPI; /* should have a FireWire */
2617 cts->transport_version = 2;
2618 spi->valid = CTS_SPI_VALID_DISC;
2619 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
2620 scsi->valid = CTS_SCSI_VALID_TQ;
2621 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2622SBP_DEBUG(1)
2623 printf("%s:%d:%jx XPT_GET_TRAN_SETTINGS:.\n",
2624 device_get_nameunit(sbp->fd.dev),
2625 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2626END_DEBUG
2627 cts->ccb_h.status = CAM_REQ_CMP;
2628 xpt_done(ccb);
2629 break;
2630 }
2631 case XPT_ABORT:
2632 ccb->ccb_h.status = CAM_UA_ABORT;
2633 xpt_done(ccb);
2634 break;
2635 case XPT_SET_TRAN_SETTINGS:
2636 /* XXX */
2637 default:
2638 ccb->ccb_h.status = CAM_REQ_INVALID;
2639 xpt_done(ccb);
2640 break;
2641 }
2642 return;
2643}
2644
2645static void
2483 ccb->ccb_h.status = CAM_REQ_INVALID;
2484 xpt_done(ccb);
2485 break;
2486 }
2487SBP_DEBUG(1)
2488 printf("%s:%d:%d:%jx:XPT_CALC_GEOMETRY: "
2489#if defined(__DragonFly__) || __FreeBSD_version < 500000
2490 "Volume size = %d\n",
2491#else
2492 "Volume size = %jd\n",
2493#endif
2494 device_get_nameunit(sbp->fd.dev),
2495 cam_sim_path(sbp->sim),
2496 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun,
2497#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2498 (uintmax_t)
2499#endif
2500 ccg->volume_size);
2501END_DEBUG
2502
2503#if defined(__DragonFly__) || __FreeBSD_version < 501100
2504 size_mb = ccg->volume_size
2505 / ((1024L * 1024L) / ccg->block_size);
2506
2507 if (size_mb > 1024 && extended) {
2508 ccg->heads = 255;
2509 ccg->secs_per_track = 63;
2510 } else {
2511 ccg->heads = 64;
2512 ccg->secs_per_track = 32;
2513 }
2514 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2515 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2516 ccb->ccb_h.status = CAM_REQ_CMP;
2517#else
2518 cam_calc_geometry(ccg, /*extended*/1);
2519#endif
2520 xpt_done(ccb);
2521 break;
2522 }
2523 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
2524 {
2525
2526SBP_DEBUG(1)
2527 printf("%s:%d:XPT_RESET_BUS: \n",
2528 device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
2529END_DEBUG
2530
2531 ccb->ccb_h.status = CAM_REQ_INVALID;
2532 xpt_done(ccb);
2533 break;
2534 }
2535 case XPT_PATH_INQ: /* Path routing inquiry */
2536 {
2537 struct ccb_pathinq *cpi = &ccb->cpi;
2538
2539SBP_DEBUG(1)
2540 printf("%s:%d:%jx XPT_PATH_INQ:.\n",
2541 device_get_nameunit(sbp->fd.dev),
2542 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2543END_DEBUG
2544 cpi->version_num = 1; /* XXX??? */
2545 cpi->hba_inquiry = PI_TAG_ABLE;
2546 cpi->target_sprt = 0;
2547 cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
2548 cpi->hba_eng_cnt = 0;
2549 cpi->max_target = SBP_NUM_TARGETS - 1;
2550 cpi->max_lun = SBP_NUM_LUNS - 1;
2551 cpi->initiator_id = SBP_INITIATOR;
2552 cpi->bus_id = sim->bus_id;
2553 cpi->base_transfer_speed = 400 * 1000 / 8;
2554 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2555 strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
2556 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
2557 cpi->unit_number = sim->unit_number;
2558 cpi->transport = XPORT_SPI; /* XX should have a FireWire */
2559 cpi->transport_version = 2;
2560 cpi->protocol = PROTO_SCSI;
2561 cpi->protocol_version = SCSI_REV_2;
2562
2563 cpi->ccb_h.status = CAM_REQ_CMP;
2564 xpt_done(ccb);
2565 break;
2566 }
2567 case XPT_GET_TRAN_SETTINGS:
2568 {
2569 struct ccb_trans_settings *cts = &ccb->cts;
2570 struct ccb_trans_settings_scsi *scsi =
2571 &cts->proto_specific.scsi;
2572 struct ccb_trans_settings_spi *spi =
2573 &cts->xport_specific.spi;
2574
2575 cts->protocol = PROTO_SCSI;
2576 cts->protocol_version = SCSI_REV_2;
2577 cts->transport = XPORT_SPI; /* should have a FireWire */
2578 cts->transport_version = 2;
2579 spi->valid = CTS_SPI_VALID_DISC;
2580 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
2581 scsi->valid = CTS_SCSI_VALID_TQ;
2582 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2583SBP_DEBUG(1)
2584 printf("%s:%d:%jx XPT_GET_TRAN_SETTINGS:.\n",
2585 device_get_nameunit(sbp->fd.dev),
2586 ccb->ccb_h.target_id, (uintmax_t)ccb->ccb_h.target_lun);
2587END_DEBUG
2588 cts->ccb_h.status = CAM_REQ_CMP;
2589 xpt_done(ccb);
2590 break;
2591 }
2592 case XPT_ABORT:
2593 ccb->ccb_h.status = CAM_UA_ABORT;
2594 xpt_done(ccb);
2595 break;
2596 case XPT_SET_TRAN_SETTINGS:
2597 /* XXX */
2598 default:
2599 ccb->ccb_h.status = CAM_REQ_INVALID;
2600 xpt_done(ccb);
2601 break;
2602 }
2603 return;
2604}
2605
2606static void
2646sbp_action(struct cam_sim *sim, union ccb *ccb)
2647{
2648 int s;
2649
2650 s = splfw();
2651 sbp_action1(sim, ccb);
2652 splx(s);
2653}
2654
2655static void
2656sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error)
2657{
2658 int i;
2659 struct sbp_ocb *ocb;
2660 struct sbp_ocb *prev;
2661 bus_dma_segment_t *s;
2662
2663 if (error)
2664 printf("sbp_execute_ocb: error=%d\n", error);
2665
2666 ocb = (struct sbp_ocb *)arg;
2667
2668SBP_DEBUG(2)
2669 printf("sbp_execute_ocb: seg %d", seg);
2670 for (i = 0; i < seg; i++)
2671#if defined(__DragonFly__) || __FreeBSD_version < 500000
2672 printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len);
2673#else
2674 printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr,
2675 (uintmax_t)segments[i].ds_len);
2676#endif
2677 printf("\n");
2678END_DEBUG
2679
2680 if (seg == 1) {
2681 /* direct pointer */
2682 s = &segments[0];
2683 if (s->ds_len > SBP_SEG_MAX)
2684 panic("ds_len > SBP_SEG_MAX, fix busdma code");
2685 ocb->orb[3] = htonl(s->ds_addr);
2686 ocb->orb[4] |= htonl(s->ds_len);
2687 } else if(seg > 1) {
2688 /* page table */
2689 for (i = 0; i < seg; i++) {
2690 s = &segments[i];
2691SBP_DEBUG(0)
2692 /* XXX LSI Logic "< 16 byte" bug might be hit */
2693 if (s->ds_len < 16)
2694 printf("sbp_execute_ocb: warning, "
2695#if defined(__DragonFly__) || __FreeBSD_version < 500000
2696 "segment length(%d) is less than 16."
2697#else
2698 "segment length(%zd) is less than 16."
2699#endif
2700 "(seg=%d/%d)\n", (size_t)s->ds_len, i+1, seg);
2701END_DEBUG
2702 if (s->ds_len > SBP_SEG_MAX)
2703 panic("ds_len > SBP_SEG_MAX, fix busdma code");
2704 ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
2705 ocb->ind_ptr[i].lo = htonl(s->ds_addr);
2706 }
2707 ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
2708 }
2709
2710 if (seg > 0)
2711 bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap,
2712 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2713 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2714 prev = sbp_enqueue_ocb(ocb->sdev, ocb);
2715 fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE);
2716 if (use_doorbell) {
2717 if (prev == NULL) {
2718 if (ocb->sdev->last_ocb != NULL)
2719 sbp_doorbell(ocb->sdev);
2720 else
2721 sbp_orb_pointer(ocb->sdev, ocb);
2722 }
2723 } else {
2724 if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) {
2725 ocb->sdev->flags &= ~ORB_LINK_DEAD;
2726 sbp_orb_pointer(ocb->sdev, ocb);
2727 }
2728 }
2729}
2730
2731static void
2732sbp_poll(struct cam_sim *sim)
2733{
2734 struct sbp_softc *sbp;
2735 struct firewire_comm *fc;
2736
2737 sbp = (struct sbp_softc *)sim->softc;
2738 fc = sbp->fd.fc;
2739
2740 fc->poll(fc, 0, -1);
2741
2742 return;
2743}
2744
2745static struct sbp_ocb *
2746sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
2747{
2748 struct sbp_ocb *ocb;
2749 struct sbp_ocb *next;
2607sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error)
2608{
2609 int i;
2610 struct sbp_ocb *ocb;
2611 struct sbp_ocb *prev;
2612 bus_dma_segment_t *s;
2613
2614 if (error)
2615 printf("sbp_execute_ocb: error=%d\n", error);
2616
2617 ocb = (struct sbp_ocb *)arg;
2618
2619SBP_DEBUG(2)
2620 printf("sbp_execute_ocb: seg %d", seg);
2621 for (i = 0; i < seg; i++)
2622#if defined(__DragonFly__) || __FreeBSD_version < 500000
2623 printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len);
2624#else
2625 printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr,
2626 (uintmax_t)segments[i].ds_len);
2627#endif
2628 printf("\n");
2629END_DEBUG
2630
2631 if (seg == 1) {
2632 /* direct pointer */
2633 s = &segments[0];
2634 if (s->ds_len > SBP_SEG_MAX)
2635 panic("ds_len > SBP_SEG_MAX, fix busdma code");
2636 ocb->orb[3] = htonl(s->ds_addr);
2637 ocb->orb[4] |= htonl(s->ds_len);
2638 } else if(seg > 1) {
2639 /* page table */
2640 for (i = 0; i < seg; i++) {
2641 s = &segments[i];
2642SBP_DEBUG(0)
2643 /* XXX LSI Logic "< 16 byte" bug might be hit */
2644 if (s->ds_len < 16)
2645 printf("sbp_execute_ocb: warning, "
2646#if defined(__DragonFly__) || __FreeBSD_version < 500000
2647 "segment length(%d) is less than 16."
2648#else
2649 "segment length(%zd) is less than 16."
2650#endif
2651 "(seg=%d/%d)\n", (size_t)s->ds_len, i+1, seg);
2652END_DEBUG
2653 if (s->ds_len > SBP_SEG_MAX)
2654 panic("ds_len > SBP_SEG_MAX, fix busdma code");
2655 ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
2656 ocb->ind_ptr[i].lo = htonl(s->ds_addr);
2657 }
2658 ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
2659 }
2660
2661 if (seg > 0)
2662 bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap,
2663 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2664 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2665 prev = sbp_enqueue_ocb(ocb->sdev, ocb);
2666 fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE);
2667 if (use_doorbell) {
2668 if (prev == NULL) {
2669 if (ocb->sdev->last_ocb != NULL)
2670 sbp_doorbell(ocb->sdev);
2671 else
2672 sbp_orb_pointer(ocb->sdev, ocb);
2673 }
2674 } else {
2675 if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) {
2676 ocb->sdev->flags &= ~ORB_LINK_DEAD;
2677 sbp_orb_pointer(ocb->sdev, ocb);
2678 }
2679 }
2680}
2681
2682static void
2683sbp_poll(struct cam_sim *sim)
2684{
2685 struct sbp_softc *sbp;
2686 struct firewire_comm *fc;
2687
2688 sbp = (struct sbp_softc *)sim->softc;
2689 fc = sbp->fd.fc;
2690
2691 fc->poll(fc, 0, -1);
2692
2693 return;
2694}
2695
2696static struct sbp_ocb *
2697sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
2698{
2699 struct sbp_ocb *ocb;
2700 struct sbp_ocb *next;
2750 int s = splfw(), order = 0;
2701 int order = 0;
2751
2752SBP_DEBUG(1)
2753 device_printf(sdev->target->sbp->fd.dev,
2754#if defined(__DragonFly__) || __FreeBSD_version < 500000
2755 "%s:%s 0x%08lx src %d\n",
2756#else
2757 "%s:%s 0x%08x src %d\n",
2758#endif
2759 __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src);
2760END_DEBUG
2702
2703SBP_DEBUG(1)
2704 device_printf(sdev->target->sbp->fd.dev,
2705#if defined(__DragonFly__) || __FreeBSD_version < 500000
2706 "%s:%s 0x%08lx src %d\n",
2707#else
2708 "%s:%s 0x%08x src %d\n",
2709#endif
2710 __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src);
2711END_DEBUG
2761 SBP_LOCK(sdev->target->sbp);
2762 for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
2763 next = STAILQ_NEXT(ocb, ocb);
2712 SBP_LOCK_ASSERT(sdev->target->sbp);
2713 STAILQ_FOREACH_SAFE(ocb, &sdev->ocbs, ocb, next) {
2764 if (OCB_MATCH(ocb, sbp_status)) {
2765 /* found */
2766 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2767 if (ocb->ccb != NULL)
2714 if (OCB_MATCH(ocb, sbp_status)) {
2715 /* found */
2716 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2717 if (ocb->ccb != NULL)
2768 untimeout(sbp_timeout, (caddr_t)ocb,
2769 ocb->timeout_ch);
2718 callout_stop(&ocb->timer);
2770 if (ntohl(ocb->orb[4]) & 0xffff) {
2771 bus_dmamap_sync(sdev->target->sbp->dmat,
2772 ocb->dmamap,
2773 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2774 BUS_DMASYNC_POSTREAD :
2775 BUS_DMASYNC_POSTWRITE);
2776 bus_dmamap_unload(sdev->target->sbp->dmat,
2777 ocb->dmamap);
2778 }
2779 if (!use_doorbell) {
2780 if (sbp_status->src == SRC_NO_NEXT) {
2781 if (next != NULL)
2782 sbp_orb_pointer(sdev, next);
2783 else if (order > 0) {
2784 /*
2785 * Unordered execution
2786 * We need to send pointer for
2787 * next ORB
2788 */
2789 sdev->flags |= ORB_LINK_DEAD;
2790 }
2791 }
2792 } else {
2793 /*
2794 * XXX this is not correct for unordered
2795 * execution.
2796 */
2797 if (sdev->last_ocb != NULL) {
2719 if (ntohl(ocb->orb[4]) & 0xffff) {
2720 bus_dmamap_sync(sdev->target->sbp->dmat,
2721 ocb->dmamap,
2722 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2723 BUS_DMASYNC_POSTREAD :
2724 BUS_DMASYNC_POSTWRITE);
2725 bus_dmamap_unload(sdev->target->sbp->dmat,
2726 ocb->dmamap);
2727 }
2728 if (!use_doorbell) {
2729 if (sbp_status->src == SRC_NO_NEXT) {
2730 if (next != NULL)
2731 sbp_orb_pointer(sdev, next);
2732 else if (order > 0) {
2733 /*
2734 * Unordered execution
2735 * We need to send pointer for
2736 * next ORB
2737 */
2738 sdev->flags |= ORB_LINK_DEAD;
2739 }
2740 }
2741 } else {
2742 /*
2743 * XXX this is not correct for unordered
2744 * execution.
2745 */
2746 if (sdev->last_ocb != NULL) {
2798 SBP_UNLOCK(sdev->target->sbp);
2799 sbp_free_ocb(sdev, sdev->last_ocb);
2747 sbp_free_ocb(sdev, sdev->last_ocb);
2800 SBP_LOCK(sdev->target->sbp);
2801 }
2802 sdev->last_ocb = ocb;
2803 if (next != NULL &&
2804 sbp_status->src == SRC_NO_NEXT)
2805 sbp_doorbell(sdev);
2806 }
2807 break;
2808 } else
2809 order ++;
2810 }
2748 }
2749 sdev->last_ocb = ocb;
2750 if (next != NULL &&
2751 sbp_status->src == SRC_NO_NEXT)
2752 sbp_doorbell(sdev);
2753 }
2754 break;
2755 } else
2756 order ++;
2757 }
2811 SBP_UNLOCK(sdev->target->sbp);
2812 splx(s);
2813SBP_DEBUG(0)
2814 if (ocb && order > 0) {
2815 device_printf(sdev->target->sbp->fd.dev,
2816 "%s:%s unordered execution order:%d\n",
2817 __func__, sdev->bustgtlun, order);
2818 }
2819END_DEBUG
2820 return (ocb);
2821}
2822
2823static struct sbp_ocb *
2824sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2825{
2758SBP_DEBUG(0)
2759 if (ocb && order > 0) {
2760 device_printf(sdev->target->sbp->fd.dev,
2761 "%s:%s unordered execution order:%d\n",
2762 __func__, sdev->bustgtlun, order);
2763 }
2764END_DEBUG
2765 return (ocb);
2766}
2767
2768static struct sbp_ocb *
2769sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2770{
2826 int s = splfw();
2827 struct sbp_ocb *prev, *prev2;
2828
2771 struct sbp_ocb *prev, *prev2;
2772
2829 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
2773 SBP_LOCK_ASSERT(sdev->target->sbp);
2830SBP_DEBUG(1)
2831 device_printf(sdev->target->sbp->fd.dev,
2832#if defined(__DragonFly__) || __FreeBSD_version < 500000
2833 "%s:%s 0x%08x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2834#else
2835 "%s:%s 0x%08jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2836#endif
2837END_DEBUG
2838 prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2839 STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2840
2841 if (ocb->ccb != NULL)
2774SBP_DEBUG(1)
2775 device_printf(sdev->target->sbp->fd.dev,
2776#if defined(__DragonFly__) || __FreeBSD_version < 500000
2777 "%s:%s 0x%08x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2778#else
2779 "%s:%s 0x%08jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2780#endif
2781END_DEBUG
2782 prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2783 STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2784
2785 if (ocb->ccb != NULL)
2842 ocb->timeout_ch = timeout(sbp_timeout, (caddr_t)ocb,
2843 (ocb->ccb->ccb_h.timeout * hz) / 1000);
2786 callout_reset(&ocb->timer, (ocb->ccb->ccb_h.timeout * hz) / 1000,
2787 sbp_timeout, ocb);
2844
2845 if (use_doorbell && prev == NULL)
2846 prev2 = sdev->last_ocb;
2847
2848 if (prev2 != NULL && (ocb->sdev->flags & ORB_LINK_DEAD) == 0) {
2849SBP_DEBUG(1)
2850#if defined(__DragonFly__) || __FreeBSD_version < 500000
2851 printf("linking chain 0x%x -> 0x%x\n",
2852 prev2->bus_addr, ocb->bus_addr);
2853#else
2854 printf("linking chain 0x%jx -> 0x%jx\n",
2855 (uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr);
2856#endif
2857END_DEBUG
2858 /*
2859 * Suppress compiler optimization so that orb[1] must be written first.
2860 * XXX We may need an explicit memory barrier for other architectures
2861 * other than i386/amd64.
2862 */
2863 *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr);
2864 *(volatile uint32_t *)&prev2->orb[0] = 0;
2865 }
2788
2789 if (use_doorbell && prev == NULL)
2790 prev2 = sdev->last_ocb;
2791
2792 if (prev2 != NULL && (ocb->sdev->flags & ORB_LINK_DEAD) == 0) {
2793SBP_DEBUG(1)
2794#if defined(__DragonFly__) || __FreeBSD_version < 500000
2795 printf("linking chain 0x%x -> 0x%x\n",
2796 prev2->bus_addr, ocb->bus_addr);
2797#else
2798 printf("linking chain 0x%jx -> 0x%jx\n",
2799 (uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr);
2800#endif
2801END_DEBUG
2802 /*
2803 * Suppress compiler optimization so that orb[1] must be written first.
2804 * XXX We may need an explicit memory barrier for other architectures
2805 * other than i386/amd64.
2806 */
2807 *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr);
2808 *(volatile uint32_t *)&prev2->orb[0] = 0;
2809 }
2866 splx(s);
2867
2868 return prev;
2869}
2870
2871static struct sbp_ocb *
2872sbp_get_ocb(struct sbp_dev *sdev)
2873{
2874 struct sbp_ocb *ocb;
2810
2811 return prev;
2812}
2813
2814static struct sbp_ocb *
2815sbp_get_ocb(struct sbp_dev *sdev)
2816{
2817 struct sbp_ocb *ocb;
2875 int s = splfw();
2876
2818
2877 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
2819 SBP_LOCK_ASSERT(sdev->target->sbp);
2878 ocb = STAILQ_FIRST(&sdev->free_ocbs);
2879 if (ocb == NULL) {
2880 sdev->flags |= ORB_SHORTAGE;
2881 printf("ocb shortage!!!\n");
2820 ocb = STAILQ_FIRST(&sdev->free_ocbs);
2821 if (ocb == NULL) {
2822 sdev->flags |= ORB_SHORTAGE;
2823 printf("ocb shortage!!!\n");
2882 splx(s);
2883 return NULL;
2884 }
2885 STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
2824 return NULL;
2825 }
2826 STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
2886 splx(s);
2887 ocb->ccb = NULL;
2888 return (ocb);
2889}
2890
2891static void
2892sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2893{
2894 ocb->flags = 0;
2895 ocb->ccb = NULL;
2896
2827 ocb->ccb = NULL;
2828 return (ocb);
2829}
2830
2831static void
2832sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2833{
2834 ocb->flags = 0;
2835 ocb->ccb = NULL;
2836
2897 SBP_LOCK(sdev->target->sbp);
2837 SBP_LOCK_ASSERT(sdev->target->sbp);
2898 STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
2899 if ((sdev->flags & ORB_SHORTAGE) != 0) {
2900 int count;
2901
2902 sdev->flags &= ~ORB_SHORTAGE;
2903 count = sdev->freeze;
2904 sdev->freeze = 0;
2905 xpt_release_devq(sdev->path, count, TRUE);
2906 }
2838 STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
2839 if ((sdev->flags & ORB_SHORTAGE) != 0) {
2840 int count;
2841
2842 sdev->flags &= ~ORB_SHORTAGE;
2843 count = sdev->freeze;
2844 sdev->freeze = 0;
2845 xpt_release_devq(sdev->path, count, TRUE);
2846 }
2907 SBP_UNLOCK(sdev->target->sbp);
2908}
2909
2910static void
2911sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2912{
2913 struct sbp_dev *sdev;
2914
2915 sdev = ocb->sdev;
2847}
2848
2849static void
2850sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2851{
2852 struct sbp_dev *sdev;
2853
2854 sdev = ocb->sdev;
2855 SBP_LOCK_ASSERT(sdev->target->sbp);
2916SBP_DEBUG(0)
2917 device_printf(sdev->target->sbp->fd.dev,
2918#if defined(__DragonFly__) || __FreeBSD_version < 500000
2919 "%s:%s 0x%x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2920#else
2921 "%s:%s 0x%jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2922#endif
2923END_DEBUG
2924SBP_DEBUG(1)
2925 if (ocb->ccb != NULL)
2926 sbp_print_scsi_cmd(ocb);
2927END_DEBUG
2928 if (ntohl(ocb->orb[4]) & 0xffff) {
2929 bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
2930 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2931 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
2932 bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
2933 }
2934 if (ocb->ccb != NULL) {
2856SBP_DEBUG(0)
2857 device_printf(sdev->target->sbp->fd.dev,
2858#if defined(__DragonFly__) || __FreeBSD_version < 500000
2859 "%s:%s 0x%x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2860#else
2861 "%s:%s 0x%jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2862#endif
2863END_DEBUG
2864SBP_DEBUG(1)
2865 if (ocb->ccb != NULL)
2866 sbp_print_scsi_cmd(ocb);
2867END_DEBUG
2868 if (ntohl(ocb->orb[4]) & 0xffff) {
2869 bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
2870 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2871 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
2872 bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
2873 }
2874 if (ocb->ccb != NULL) {
2935 untimeout(sbp_timeout, (caddr_t)ocb,
2936 ocb->timeout_ch);
2875 callout_stop(&ocb->timer);
2937 ocb->ccb->ccb_h.status = status;
2876 ocb->ccb->ccb_h.status = status;
2938 SBP_LOCK(sdev->target->sbp);
2939 xpt_done(ocb->ccb);
2877 xpt_done(ocb->ccb);
2940 SBP_UNLOCK(sdev->target->sbp);
2941 }
2942 sbp_free_ocb(sdev, ocb);
2943}
2944
2945static void
2946sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2947{
2878 }
2879 sbp_free_ocb(sdev, ocb);
2880}
2881
2882static void
2883sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2884{
2948 int s;
2949 struct sbp_ocb *ocb, *next;
2950 STAILQ_HEAD(, sbp_ocb) temp;
2951
2885 struct sbp_ocb *ocb, *next;
2886 STAILQ_HEAD(, sbp_ocb) temp;
2887
2952 s = splfw();
2953
2954 STAILQ_INIT(&temp);
2888 STAILQ_INIT(&temp);
2955 SBP_LOCK(sdev->target->sbp);
2889 SBP_LOCK_ASSERT(sdev->target->sbp);
2956 STAILQ_CONCAT(&temp, &sdev->ocbs);
2957 STAILQ_INIT(&sdev->ocbs);
2890 STAILQ_CONCAT(&temp, &sdev->ocbs);
2891 STAILQ_INIT(&sdev->ocbs);
2958 SBP_UNLOCK(sdev->target->sbp);
2959
2892
2960 for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
2961 next = STAILQ_NEXT(ocb, ocb);
2893 STAILQ_FOREACH_SAFE(ocb, &temp, ocb, next) {
2962 sbp_abort_ocb(ocb, status);
2963 }
2964 if (sdev->last_ocb != NULL) {
2965 sbp_free_ocb(sdev, sdev->last_ocb);
2966 sdev->last_ocb = NULL;
2967 }
2894 sbp_abort_ocb(ocb, status);
2895 }
2896 if (sdev->last_ocb != NULL) {
2897 sbp_free_ocb(sdev, sdev->last_ocb);
2898 sdev->last_ocb = NULL;
2899 }
2968
2969 splx(s);
2970}
2971
2972static devclass_t sbp_devclass;
2973
2974static device_method_t sbp_methods[] = {
2975 /* device interface */
2976 DEVMETHOD(device_identify, sbp_identify),
2977 DEVMETHOD(device_probe, sbp_probe),
2978 DEVMETHOD(device_attach, sbp_attach),
2979 DEVMETHOD(device_detach, sbp_detach),
2980 DEVMETHOD(device_shutdown, sbp_shutdown),
2981
2982 { 0, 0 }
2983};
2984
2985static driver_t sbp_driver = {
2986 "sbp",
2987 sbp_methods,
2988 sizeof(struct sbp_softc),
2989};
2990#ifdef __DragonFly__
2991DECLARE_DUMMY_MODULE(sbp);
2992#endif
2993DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
2994MODULE_VERSION(sbp, 1);
2995MODULE_DEPEND(sbp, firewire, 1, 1, 1);
2996MODULE_DEPEND(sbp, cam, 1, 1, 1);
2900}
2901
2902static devclass_t sbp_devclass;
2903
2904static device_method_t sbp_methods[] = {
2905 /* device interface */
2906 DEVMETHOD(device_identify, sbp_identify),
2907 DEVMETHOD(device_probe, sbp_probe),
2908 DEVMETHOD(device_attach, sbp_attach),
2909 DEVMETHOD(device_detach, sbp_detach),
2910 DEVMETHOD(device_shutdown, sbp_shutdown),
2911
2912 { 0, 0 }
2913};
2914
2915static driver_t sbp_driver = {
2916 "sbp",
2917 sbp_methods,
2918 sizeof(struct sbp_softc),
2919};
2920#ifdef __DragonFly__
2921DECLARE_DUMMY_MODULE(sbp);
2922#endif
2923DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
2924MODULE_VERSION(sbp, 1);
2925MODULE_DEPEND(sbp, firewire, 1, 1, 1);
2926MODULE_DEPEND(sbp, cam, 1, 1, 1);