1 |
62 |
marcus.erl |
/*
|
2 |
|
|
* SBP2 driver (SCSI over IEEE1394)
|
3 |
|
|
*
|
4 |
|
|
* Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
|
5 |
|
|
*
|
6 |
|
|
* This program is free software; you can redistribute it and/or modify
|
7 |
|
|
* it under the terms of the GNU General Public License as published by
|
8 |
|
|
* the Free Software Foundation; either version 2 of the License, or
|
9 |
|
|
* (at your option) any later version.
|
10 |
|
|
*
|
11 |
|
|
* This program is distributed in the hope that it will be useful,
|
12 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
|
|
* GNU General Public License for more details.
|
15 |
|
|
*
|
16 |
|
|
* You should have received a copy of the GNU General Public License
|
17 |
|
|
* along with this program; if not, write to the Free Software Foundation,
|
18 |
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
19 |
|
|
*/
|
20 |
|
|
|
21 |
|
|
/*
|
22 |
|
|
* The basic structure of this driver is based on the old storage driver,
|
23 |
|
|
* drivers/ieee1394/sbp2.c, originally written by
|
24 |
|
|
* James Goodwin <jamesg@filanet.com>
|
25 |
|
|
* with later contributions and ongoing maintenance from
|
26 |
|
|
* Ben Collins <bcollins@debian.org>,
|
27 |
|
|
* Stefan Richter <stefanr@s5r6.in-berlin.de>
|
28 |
|
|
* and many others.
|
29 |
|
|
*/
|
30 |
|
|
|
31 |
|
|
#include <linux/kernel.h>
|
32 |
|
|
#include <linux/module.h>
|
33 |
|
|
#include <linux/moduleparam.h>
|
34 |
|
|
#include <linux/mod_devicetable.h>
|
35 |
|
|
#include <linux/device.h>
|
36 |
|
|
#include <linux/scatterlist.h>
|
37 |
|
|
#include <linux/dma-mapping.h>
|
38 |
|
|
#include <linux/blkdev.h>
|
39 |
|
|
#include <linux/string.h>
|
40 |
|
|
#include <linux/stringify.h>
|
41 |
|
|
#include <linux/timer.h>
|
42 |
|
|
#include <linux/workqueue.h>
|
43 |
|
|
|
44 |
|
|
#include <scsi/scsi.h>
|
45 |
|
|
#include <scsi/scsi_cmnd.h>
|
46 |
|
|
#include <scsi/scsi_device.h>
|
47 |
|
|
#include <scsi/scsi_host.h>
|
48 |
|
|
|
49 |
|
|
#include "fw-transaction.h"
|
50 |
|
|
#include "fw-topology.h"
|
51 |
|
|
#include "fw-device.h"
|
52 |
|
|
|
53 |
|
|
/*
|
54 |
|
|
* So far only bridges from Oxford Semiconductor are known to support
|
55 |
|
|
* concurrent logins. Depending on firmware, four or two concurrent logins
|
56 |
|
|
* are possible on OXFW911 and newer Oxsemi bridges.
|
57 |
|
|
*
|
58 |
|
|
* Concurrent logins are useful together with cluster filesystems.
|
59 |
|
|
*/
|
60 |
|
|
static int sbp2_param_exclusive_login = 1;
|
61 |
|
|
module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);
|
62 |
|
|
MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
|
63 |
|
|
"(default = Y, use N for concurrent initiators)");
|
64 |
|
|
|
65 |
|
|
/*
|
66 |
|
|
* Flags for firmware oddities
|
67 |
|
|
*
|
68 |
|
|
* - 128kB max transfer
|
69 |
|
|
* Limit transfer size. Necessary for some old bridges.
|
70 |
|
|
*
|
71 |
|
|
* - 36 byte inquiry
|
72 |
|
|
* When scsi_mod probes the device, let the inquiry command look like that
|
73 |
|
|
* from MS Windows.
|
74 |
|
|
*
|
75 |
|
|
* - skip mode page 8
|
76 |
|
|
* Suppress sending of mode_sense for mode page 8 if the device pretends to
|
77 |
|
|
* support the SCSI Primary Block commands instead of Reduced Block Commands.
|
78 |
|
|
*
|
79 |
|
|
* - fix capacity
|
80 |
|
|
* Tell sd_mod to correct the last sector number reported by read_capacity.
|
81 |
|
|
* Avoids access beyond actual disk limits on devices with an off-by-one bug.
|
82 |
|
|
* Don't use this with devices which don't have this bug.
|
83 |
|
|
*
|
84 |
|
|
* - override internal blacklist
|
85 |
|
|
* Instead of adding to the built-in blacklist, use only the workarounds
|
86 |
|
|
* specified in the module load parameter.
|
87 |
|
|
* Useful if a blacklist entry interfered with a non-broken device.
|
88 |
|
|
*/
|
89 |
|
|
#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
|
90 |
|
|
#define SBP2_WORKAROUND_INQUIRY_36 0x2
|
91 |
|
|
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
|
92 |
|
|
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
|
93 |
|
|
#define SBP2_WORKAROUND_OVERRIDE 0x100
|
94 |
|
|
|
95 |
|
|
static int sbp2_param_workarounds;
|
96 |
|
|
module_param_named(workarounds, sbp2_param_workarounds, int, 0644);
|
97 |
|
|
MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
|
98 |
|
|
", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS)
|
99 |
|
|
", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
|
100 |
|
|
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
|
101 |
|
|
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
|
102 |
|
|
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
|
103 |
|
|
", or a combination)");
|
104 |
|
|
|
105 |
|
|
/* I don't know why the SCSI stack doesn't define something like this... */
|
106 |
|
|
typedef void (*scsi_done_fn_t)(struct scsi_cmnd *);
|
107 |
|
|
|
108 |
|
|
static const char sbp2_driver_name[] = "sbp2";
|
109 |
|
|
|
110 |
|
|
/*
|
111 |
|
|
* We create one struct sbp2_logical_unit per SBP-2 Logical Unit Number Entry
|
112 |
|
|
* and one struct scsi_device per sbp2_logical_unit.
|
113 |
|
|
*/
|
114 |
|
|
struct sbp2_logical_unit {
|
115 |
|
|
struct sbp2_target *tgt;
|
116 |
|
|
struct list_head link;
|
117 |
|
|
struct scsi_device *sdev;
|
118 |
|
|
struct fw_address_handler address_handler;
|
119 |
|
|
struct list_head orb_list;
|
120 |
|
|
|
121 |
|
|
u64 command_block_agent_address;
|
122 |
|
|
u16 lun;
|
123 |
|
|
int login_id;
|
124 |
|
|
|
125 |
|
|
/*
|
126 |
|
|
* The generation is updated once we've logged in or reconnected
|
127 |
|
|
* to the logical unit. Thus, I/O to the device will automatically
|
128 |
|
|
* fail and get retried if it happens in a window where the device
|
129 |
|
|
* is not ready, e.g. after a bus reset but before we reconnect.
|
130 |
|
|
*/
|
131 |
|
|
int generation;
|
132 |
|
|
int retries;
|
133 |
|
|
struct delayed_work work;
|
134 |
|
|
};
|
135 |
|
|
|
136 |
|
|
/*
|
137 |
|
|
* We create one struct sbp2_target per IEEE 1212 Unit Directory
|
138 |
|
|
* and one struct Scsi_Host per sbp2_target.
|
139 |
|
|
*/
|
140 |
|
|
struct sbp2_target {
|
141 |
|
|
struct kref kref;
|
142 |
|
|
struct fw_unit *unit;
|
143 |
|
|
|
144 |
|
|
u64 management_agent_address;
|
145 |
|
|
int directory_id;
|
146 |
|
|
int node_id;
|
147 |
|
|
int address_high;
|
148 |
|
|
|
149 |
|
|
unsigned workarounds;
|
150 |
|
|
struct list_head lu_list;
|
151 |
|
|
};
|
152 |
|
|
|
153 |
|
|
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
|
154 |
|
|
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
|
155 |
|
|
#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
|
156 |
|
|
|
157 |
|
|
#define SBP2_ORB_NULL 0x80000000
|
158 |
|
|
|
159 |
|
|
#define SBP2_DIRECTION_TO_MEDIA 0x0
|
160 |
|
|
#define SBP2_DIRECTION_FROM_MEDIA 0x1
|
161 |
|
|
|
162 |
|
|
/* Unit directory keys */
|
163 |
|
|
#define SBP2_CSR_FIRMWARE_REVISION 0x3c
|
164 |
|
|
#define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14
|
165 |
|
|
#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4
|
166 |
|
|
|
167 |
|
|
/* Management orb opcodes */
|
168 |
|
|
#define SBP2_LOGIN_REQUEST 0x0
|
169 |
|
|
#define SBP2_QUERY_LOGINS_REQUEST 0x1
|
170 |
|
|
#define SBP2_RECONNECT_REQUEST 0x3
|
171 |
|
|
#define SBP2_SET_PASSWORD_REQUEST 0x4
|
172 |
|
|
#define SBP2_LOGOUT_REQUEST 0x7
|
173 |
|
|
#define SBP2_ABORT_TASK_REQUEST 0xb
|
174 |
|
|
#define SBP2_ABORT_TASK_SET 0xc
|
175 |
|
|
#define SBP2_LOGICAL_UNIT_RESET 0xe
|
176 |
|
|
#define SBP2_TARGET_RESET_REQUEST 0xf
|
177 |
|
|
|
178 |
|
|
/* Offsets for command block agent registers */
|
179 |
|
|
#define SBP2_AGENT_STATE 0x00
|
180 |
|
|
#define SBP2_AGENT_RESET 0x04
|
181 |
|
|
#define SBP2_ORB_POINTER 0x08
|
182 |
|
|
#define SBP2_DOORBELL 0x10
|
183 |
|
|
#define SBP2_UNSOLICITED_STATUS_ENABLE 0x14
|
184 |
|
|
|
185 |
|
|
/* Status write response codes */
|
186 |
|
|
#define SBP2_STATUS_REQUEST_COMPLETE 0x0
|
187 |
|
|
#define SBP2_STATUS_TRANSPORT_FAILURE 0x1
|
188 |
|
|
#define SBP2_STATUS_ILLEGAL_REQUEST 0x2
|
189 |
|
|
#define SBP2_STATUS_VENDOR_DEPENDENT 0x3
|
190 |
|
|
|
191 |
|
|
#define STATUS_GET_ORB_HIGH(v) ((v).status & 0xffff)
|
192 |
|
|
#define STATUS_GET_SBP_STATUS(v) (((v).status >> 16) & 0xff)
|
193 |
|
|
#define STATUS_GET_LEN(v) (((v).status >> 24) & 0x07)
|
194 |
|
|
#define STATUS_GET_DEAD(v) (((v).status >> 27) & 0x01)
|
195 |
|
|
#define STATUS_GET_RESPONSE(v) (((v).status >> 28) & 0x03)
|
196 |
|
|
#define STATUS_GET_SOURCE(v) (((v).status >> 30) & 0x03)
|
197 |
|
|
#define STATUS_GET_ORB_LOW(v) ((v).orb_low)
|
198 |
|
|
#define STATUS_GET_DATA(v) ((v).data)
|
199 |
|
|
|
200 |
|
|
struct sbp2_status {
|
201 |
|
|
u32 status;
|
202 |
|
|
u32 orb_low;
|
203 |
|
|
u8 data[24];
|
204 |
|
|
};
|
205 |
|
|
|
206 |
|
|
struct sbp2_pointer {
|
207 |
|
|
u32 high;
|
208 |
|
|
u32 low;
|
209 |
|
|
};
|
210 |
|
|
|
211 |
|
|
struct sbp2_orb {
|
212 |
|
|
struct fw_transaction t;
|
213 |
|
|
struct kref kref;
|
214 |
|
|
dma_addr_t request_bus;
|
215 |
|
|
int rcode;
|
216 |
|
|
struct sbp2_pointer pointer;
|
217 |
|
|
void (*callback)(struct sbp2_orb * orb, struct sbp2_status * status);
|
218 |
|
|
struct list_head link;
|
219 |
|
|
};
|
220 |
|
|
|
221 |
|
|
#define MANAGEMENT_ORB_LUN(v) ((v))
|
222 |
|
|
#define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16)
|
223 |
|
|
#define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20)
|
224 |
|
|
#define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0)
|
225 |
|
|
#define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29)
|
226 |
|
|
#define MANAGEMENT_ORB_NOTIFY ((1) << 31)
|
227 |
|
|
|
228 |
|
|
#define MANAGEMENT_ORB_RESPONSE_LENGTH(v) ((v))
|
229 |
|
|
#define MANAGEMENT_ORB_PASSWORD_LENGTH(v) ((v) << 16)
|
230 |
|
|
|
231 |
|
|
struct sbp2_management_orb {
|
232 |
|
|
struct sbp2_orb base;
|
233 |
|
|
struct {
|
234 |
|
|
struct sbp2_pointer password;
|
235 |
|
|
struct sbp2_pointer response;
|
236 |
|
|
u32 misc;
|
237 |
|
|
u32 length;
|
238 |
|
|
struct sbp2_pointer status_fifo;
|
239 |
|
|
} request;
|
240 |
|
|
__be32 response[4];
|
241 |
|
|
dma_addr_t response_bus;
|
242 |
|
|
struct completion done;
|
243 |
|
|
struct sbp2_status status;
|
244 |
|
|
};
|
245 |
|
|
|
246 |
|
|
#define LOGIN_RESPONSE_GET_LOGIN_ID(v) ((v).misc & 0xffff)
|
247 |
|
|
#define LOGIN_RESPONSE_GET_LENGTH(v) (((v).misc >> 16) & 0xffff)
|
248 |
|
|
|
249 |
|
|
struct sbp2_login_response {
|
250 |
|
|
u32 misc;
|
251 |
|
|
struct sbp2_pointer command_block_agent;
|
252 |
|
|
u32 reconnect_hold;
|
253 |
|
|
};
|
254 |
|
|
#define COMMAND_ORB_DATA_SIZE(v) ((v))
|
255 |
|
|
#define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16)
|
256 |
|
|
#define COMMAND_ORB_PAGE_TABLE_PRESENT ((1) << 19)
|
257 |
|
|
#define COMMAND_ORB_MAX_PAYLOAD(v) ((v) << 20)
|
258 |
|
|
#define COMMAND_ORB_SPEED(v) ((v) << 24)
|
259 |
|
|
#define COMMAND_ORB_DIRECTION(v) ((v) << 27)
|
260 |
|
|
#define COMMAND_ORB_REQUEST_FORMAT(v) ((v) << 29)
|
261 |
|
|
#define COMMAND_ORB_NOTIFY ((1) << 31)
|
262 |
|
|
|
263 |
|
|
struct sbp2_command_orb {
|
264 |
|
|
struct sbp2_orb base;
|
265 |
|
|
struct {
|
266 |
|
|
struct sbp2_pointer next;
|
267 |
|
|
struct sbp2_pointer data_descriptor;
|
268 |
|
|
u32 misc;
|
269 |
|
|
u8 command_block[12];
|
270 |
|
|
} request;
|
271 |
|
|
struct scsi_cmnd *cmd;
|
272 |
|
|
scsi_done_fn_t done;
|
273 |
|
|
struct sbp2_logical_unit *lu;
|
274 |
|
|
|
275 |
|
|
struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
|
276 |
|
|
dma_addr_t page_table_bus;
|
277 |
|
|
};
|
278 |
|
|
|
279 |
|
|
/*
|
280 |
|
|
* List of devices with known bugs.
|
281 |
|
|
*
|
282 |
|
|
* The firmware_revision field, masked with 0xffff00, is the best
|
283 |
|
|
* indicator for the type of bridge chip of a device. It yields a few
|
284 |
|
|
* false positives but this did not break correctly behaving devices
|
285 |
|
|
* so far. We use ~0 as a wildcard, since the 24 bit values we get
|
286 |
|
|
* from the config rom can never match that.
|
287 |
|
|
*/
|
288 |
|
|
static const struct {
|
289 |
|
|
u32 firmware_revision;
|
290 |
|
|
u32 model;
|
291 |
|
|
unsigned workarounds;
|
292 |
|
|
} sbp2_workarounds_table[] = {
|
293 |
|
|
/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
|
294 |
|
|
.firmware_revision = 0x002800,
|
295 |
|
|
.model = 0x001010,
|
296 |
|
|
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
|
297 |
|
|
SBP2_WORKAROUND_MODE_SENSE_8,
|
298 |
|
|
},
|
299 |
|
|
/* Initio bridges, actually only needed for some older ones */ {
|
300 |
|
|
.firmware_revision = 0x000200,
|
301 |
|
|
.model = ~0,
|
302 |
|
|
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
|
303 |
|
|
},
|
304 |
|
|
/* Symbios bridge */ {
|
305 |
|
|
.firmware_revision = 0xa0b800,
|
306 |
|
|
.model = ~0,
|
307 |
|
|
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
308 |
|
|
},
|
309 |
|
|
|
310 |
|
|
/*
|
311 |
|
|
* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
|
312 |
|
|
* these iPods do not feature the read_capacity bug according
|
313 |
|
|
* to one report. Read_capacity behaviour as well as model_id
|
314 |
|
|
* could change due to Apple-supplied firmware updates though.
|
315 |
|
|
*/
|
316 |
|
|
|
317 |
|
|
/* iPod 4th generation. */ {
|
318 |
|
|
.firmware_revision = 0x0a2700,
|
319 |
|
|
.model = 0x000021,
|
320 |
|
|
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
|
321 |
|
|
},
|
322 |
|
|
/* iPod mini */ {
|
323 |
|
|
.firmware_revision = 0x0a2700,
|
324 |
|
|
.model = 0x000023,
|
325 |
|
|
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
|
326 |
|
|
},
|
327 |
|
|
/* iPod Photo */ {
|
328 |
|
|
.firmware_revision = 0x0a2700,
|
329 |
|
|
.model = 0x00007e,
|
330 |
|
|
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
|
331 |
|
|
}
|
332 |
|
|
};
|
333 |
|
|
|
334 |
|
|
static void
|
335 |
|
|
free_orb(struct kref *kref)
|
336 |
|
|
{
|
337 |
|
|
struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref);
|
338 |
|
|
|
339 |
|
|
kfree(orb);
|
340 |
|
|
}
|
341 |
|
|
|
342 |
|
|
static void
|
343 |
|
|
sbp2_status_write(struct fw_card *card, struct fw_request *request,
|
344 |
|
|
int tcode, int destination, int source,
|
345 |
|
|
int generation, int speed,
|
346 |
|
|
unsigned long long offset,
|
347 |
|
|
void *payload, size_t length, void *callback_data)
|
348 |
|
|
{
|
349 |
|
|
struct sbp2_logical_unit *lu = callback_data;
|
350 |
|
|
struct sbp2_orb *orb;
|
351 |
|
|
struct sbp2_status status;
|
352 |
|
|
size_t header_size;
|
353 |
|
|
unsigned long flags;
|
354 |
|
|
|
355 |
|
|
if (tcode != TCODE_WRITE_BLOCK_REQUEST ||
|
356 |
|
|
length == 0 || length > sizeof(status)) {
|
357 |
|
|
fw_send_response(card, request, RCODE_TYPE_ERROR);
|
358 |
|
|
return;
|
359 |
|
|
}
|
360 |
|
|
|
361 |
|
|
header_size = min(length, 2 * sizeof(u32));
|
362 |
|
|
fw_memcpy_from_be32(&status, payload, header_size);
|
363 |
|
|
if (length > header_size)
|
364 |
|
|
memcpy(status.data, payload + 8, length - header_size);
|
365 |
|
|
if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) {
|
366 |
|
|
fw_notify("non-orb related status write, not handled\n");
|
367 |
|
|
fw_send_response(card, request, RCODE_COMPLETE);
|
368 |
|
|
return;
|
369 |
|
|
}
|
370 |
|
|
|
371 |
|
|
/* Lookup the orb corresponding to this status write. */
|
372 |
|
|
spin_lock_irqsave(&card->lock, flags);
|
373 |
|
|
list_for_each_entry(orb, &lu->orb_list, link) {
|
374 |
|
|
if (STATUS_GET_ORB_HIGH(status) == 0 &&
|
375 |
|
|
STATUS_GET_ORB_LOW(status) == orb->request_bus) {
|
376 |
|
|
orb->rcode = RCODE_COMPLETE;
|
377 |
|
|
list_del(&orb->link);
|
378 |
|
|
break;
|
379 |
|
|
}
|
380 |
|
|
}
|
381 |
|
|
spin_unlock_irqrestore(&card->lock, flags);
|
382 |
|
|
|
383 |
|
|
if (&orb->link != &lu->orb_list)
|
384 |
|
|
orb->callback(orb, &status);
|
385 |
|
|
else
|
386 |
|
|
fw_error("status write for unknown orb\n");
|
387 |
|
|
|
388 |
|
|
kref_put(&orb->kref, free_orb);
|
389 |
|
|
|
390 |
|
|
fw_send_response(card, request, RCODE_COMPLETE);
|
391 |
|
|
}
|
392 |
|
|
|
393 |
|
|
static void
|
394 |
|
|
complete_transaction(struct fw_card *card, int rcode,
|
395 |
|
|
void *payload, size_t length, void *data)
|
396 |
|
|
{
|
397 |
|
|
struct sbp2_orb *orb = data;
|
398 |
|
|
unsigned long flags;
|
399 |
|
|
|
400 |
|
|
/*
|
401 |
|
|
* This is a little tricky. We can get the status write for
|
402 |
|
|
* the orb before we get this callback. The status write
|
403 |
|
|
* handler above will assume the orb pointer transaction was
|
404 |
|
|
* successful and set the rcode to RCODE_COMPLETE for the orb.
|
405 |
|
|
* So this callback only sets the rcode if it hasn't already
|
406 |
|
|
* been set and only does the cleanup if the transaction
|
407 |
|
|
* failed and we didn't already get a status write.
|
408 |
|
|
*/
|
409 |
|
|
spin_lock_irqsave(&card->lock, flags);
|
410 |
|
|
|
411 |
|
|
if (orb->rcode == -1)
|
412 |
|
|
orb->rcode = rcode;
|
413 |
|
|
if (orb->rcode != RCODE_COMPLETE) {
|
414 |
|
|
list_del(&orb->link);
|
415 |
|
|
spin_unlock_irqrestore(&card->lock, flags);
|
416 |
|
|
orb->callback(orb, NULL);
|
417 |
|
|
} else {
|
418 |
|
|
spin_unlock_irqrestore(&card->lock, flags);
|
419 |
|
|
}
|
420 |
|
|
|
421 |
|
|
kref_put(&orb->kref, free_orb);
|
422 |
|
|
}
|
423 |
|
|
|
424 |
|
|
static void
|
425 |
|
|
sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
|
426 |
|
|
int node_id, int generation, u64 offset)
|
427 |
|
|
{
|
428 |
|
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
429 |
|
|
unsigned long flags;
|
430 |
|
|
|
431 |
|
|
orb->pointer.high = 0;
|
432 |
|
|
orb->pointer.low = orb->request_bus;
|
433 |
|
|
fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
|
434 |
|
|
|
435 |
|
|
spin_lock_irqsave(&device->card->lock, flags);
|
436 |
|
|
list_add_tail(&orb->link, &lu->orb_list);
|
437 |
|
|
spin_unlock_irqrestore(&device->card->lock, flags);
|
438 |
|
|
|
439 |
|
|
/* Take a ref for the orb list and for the transaction callback. */
|
440 |
|
|
kref_get(&orb->kref);
|
441 |
|
|
kref_get(&orb->kref);
|
442 |
|
|
|
443 |
|
|
fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
|
444 |
|
|
node_id, generation, device->max_speed, offset,
|
445 |
|
|
&orb->pointer, sizeof(orb->pointer),
|
446 |
|
|
complete_transaction, orb);
|
447 |
|
|
}
|
448 |
|
|
|
449 |
|
|
static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
|
450 |
|
|
{
|
451 |
|
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
452 |
|
|
struct sbp2_orb *orb, *next;
|
453 |
|
|
struct list_head list;
|
454 |
|
|
unsigned long flags;
|
455 |
|
|
int retval = -ENOENT;
|
456 |
|
|
|
457 |
|
|
INIT_LIST_HEAD(&list);
|
458 |
|
|
spin_lock_irqsave(&device->card->lock, flags);
|
459 |
|
|
list_splice_init(&lu->orb_list, &list);
|
460 |
|
|
spin_unlock_irqrestore(&device->card->lock, flags);
|
461 |
|
|
|
462 |
|
|
list_for_each_entry_safe(orb, next, &list, link) {
|
463 |
|
|
retval = 0;
|
464 |
|
|
if (fw_cancel_transaction(device->card, &orb->t) == 0)
|
465 |
|
|
continue;
|
466 |
|
|
|
467 |
|
|
orb->rcode = RCODE_CANCELLED;
|
468 |
|
|
orb->callback(orb, NULL);
|
469 |
|
|
}
|
470 |
|
|
|
471 |
|
|
return retval;
|
472 |
|
|
}
|
473 |
|
|
|
474 |
|
|
static void
|
475 |
|
|
complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
|
476 |
|
|
{
|
477 |
|
|
struct sbp2_management_orb *orb =
|
478 |
|
|
container_of(base_orb, struct sbp2_management_orb, base);
|
479 |
|
|
|
480 |
|
|
if (status)
|
481 |
|
|
memcpy(&orb->status, status, sizeof(*status));
|
482 |
|
|
complete(&orb->done);
|
483 |
|
|
}
|
484 |
|
|
|
485 |
|
|
static int
|
486 |
|
|
sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
|
487 |
|
|
int generation, int function, int lun_or_login_id,
|
488 |
|
|
void *response)
|
489 |
|
|
{
|
490 |
|
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
491 |
|
|
struct sbp2_management_orb *orb;
|
492 |
|
|
int retval = -ENOMEM;
|
493 |
|
|
|
494 |
|
|
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
|
495 |
|
|
if (orb == NULL)
|
496 |
|
|
return -ENOMEM;
|
497 |
|
|
|
498 |
|
|
kref_init(&orb->base.kref);
|
499 |
|
|
orb->response_bus =
|
500 |
|
|
dma_map_single(device->card->device, &orb->response,
|
501 |
|
|
sizeof(orb->response), DMA_FROM_DEVICE);
|
502 |
|
|
if (dma_mapping_error(orb->response_bus))
|
503 |
|
|
goto fail_mapping_response;
|
504 |
|
|
|
505 |
|
|
orb->request.response.high = 0;
|
506 |
|
|
orb->request.response.low = orb->response_bus;
|
507 |
|
|
|
508 |
|
|
orb->request.misc =
|
509 |
|
|
MANAGEMENT_ORB_NOTIFY |
|
510 |
|
|
MANAGEMENT_ORB_FUNCTION(function) |
|
511 |
|
|
MANAGEMENT_ORB_LUN(lun_or_login_id);
|
512 |
|
|
orb->request.length =
|
513 |
|
|
MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
|
514 |
|
|
|
515 |
|
|
orb->request.status_fifo.high = lu->address_handler.offset >> 32;
|
516 |
|
|
orb->request.status_fifo.low = lu->address_handler.offset;
|
517 |
|
|
|
518 |
|
|
if (function == SBP2_LOGIN_REQUEST) {
|
519 |
|
|
orb->request.misc |=
|
520 |
|
|
MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) |
|
521 |
|
|
MANAGEMENT_ORB_RECONNECT(0);
|
522 |
|
|
}
|
523 |
|
|
|
524 |
|
|
fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
|
525 |
|
|
|
526 |
|
|
init_completion(&orb->done);
|
527 |
|
|
orb->base.callback = complete_management_orb;
|
528 |
|
|
|
529 |
|
|
orb->base.request_bus =
|
530 |
|
|
dma_map_single(device->card->device, &orb->request,
|
531 |
|
|
sizeof(orb->request), DMA_TO_DEVICE);
|
532 |
|
|
if (dma_mapping_error(orb->base.request_bus))
|
533 |
|
|
goto fail_mapping_request;
|
534 |
|
|
|
535 |
|
|
sbp2_send_orb(&orb->base, lu, node_id, generation,
|
536 |
|
|
lu->tgt->management_agent_address);
|
537 |
|
|
|
538 |
|
|
wait_for_completion_timeout(&orb->done,
|
539 |
|
|
msecs_to_jiffies(SBP2_ORB_TIMEOUT));
|
540 |
|
|
|
541 |
|
|
retval = -EIO;
|
542 |
|
|
if (sbp2_cancel_orbs(lu) == 0) {
|
543 |
|
|
fw_error("orb reply timed out, rcode=0x%02x\n",
|
544 |
|
|
orb->base.rcode);
|
545 |
|
|
goto out;
|
546 |
|
|
}
|
547 |
|
|
|
548 |
|
|
if (orb->base.rcode != RCODE_COMPLETE) {
|
549 |
|
|
fw_error("management write failed, rcode 0x%02x\n",
|
550 |
|
|
orb->base.rcode);
|
551 |
|
|
goto out;
|
552 |
|
|
}
|
553 |
|
|
|
554 |
|
|
if (STATUS_GET_RESPONSE(orb->status) != 0 ||
|
555 |
|
|
STATUS_GET_SBP_STATUS(orb->status) != 0) {
|
556 |
|
|
fw_error("error status: %d:%d\n",
|
557 |
|
|
STATUS_GET_RESPONSE(orb->status),
|
558 |
|
|
STATUS_GET_SBP_STATUS(orb->status));
|
559 |
|
|
goto out;
|
560 |
|
|
}
|
561 |
|
|
|
562 |
|
|
retval = 0;
|
563 |
|
|
out:
|
564 |
|
|
dma_unmap_single(device->card->device, orb->base.request_bus,
|
565 |
|
|
sizeof(orb->request), DMA_TO_DEVICE);
|
566 |
|
|
fail_mapping_request:
|
567 |
|
|
dma_unmap_single(device->card->device, orb->response_bus,
|
568 |
|
|
sizeof(orb->response), DMA_FROM_DEVICE);
|
569 |
|
|
fail_mapping_response:
|
570 |
|
|
if (response)
|
571 |
|
|
fw_memcpy_from_be32(response,
|
572 |
|
|
orb->response, sizeof(orb->response));
|
573 |
|
|
kref_put(&orb->base.kref, free_orb);
|
574 |
|
|
|
575 |
|
|
return retval;
|
576 |
|
|
}
|
577 |
|
|
|
578 |
|
|
static void
|
579 |
|
|
complete_agent_reset_write(struct fw_card *card, int rcode,
|
580 |
|
|
void *payload, size_t length, void *data)
|
581 |
|
|
{
|
582 |
|
|
struct fw_transaction *t = data;
|
583 |
|
|
|
584 |
|
|
kfree(t);
|
585 |
|
|
}
|
586 |
|
|
|
587 |
|
|
static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
|
588 |
|
|
{
|
589 |
|
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
590 |
|
|
struct fw_transaction *t;
|
591 |
|
|
static u32 zero;
|
592 |
|
|
|
593 |
|
|
t = kzalloc(sizeof(*t), GFP_ATOMIC);
|
594 |
|
|
if (t == NULL)
|
595 |
|
|
return -ENOMEM;
|
596 |
|
|
|
597 |
|
|
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
|
598 |
|
|
lu->tgt->node_id, lu->generation, device->max_speed,
|
599 |
|
|
lu->command_block_agent_address + SBP2_AGENT_RESET,
|
600 |
|
|
&zero, sizeof(zero), complete_agent_reset_write, t);
|
601 |
|
|
|
602 |
|
|
return 0;
|
603 |
|
|
}
|
604 |
|
|
|
605 |
|
|
static void sbp2_release_target(struct kref *kref)
|
606 |
|
|
{
|
607 |
|
|
struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref);
|
608 |
|
|
struct sbp2_logical_unit *lu, *next;
|
609 |
|
|
struct Scsi_Host *shost =
|
610 |
|
|
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
|
611 |
|
|
|
612 |
|
|
list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
|
613 |
|
|
if (lu->sdev)
|
614 |
|
|
scsi_remove_device(lu->sdev);
|
615 |
|
|
|
616 |
|
|
sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
|
617 |
|
|
SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
|
618 |
|
|
fw_core_remove_address_handler(&lu->address_handler);
|
619 |
|
|
list_del(&lu->link);
|
620 |
|
|
kfree(lu);
|
621 |
|
|
}
|
622 |
|
|
scsi_remove_host(shost);
|
623 |
|
|
fw_notify("released %s\n", tgt->unit->device.bus_id);
|
624 |
|
|
|
625 |
|
|
put_device(&tgt->unit->device);
|
626 |
|
|
scsi_host_put(shost);
|
627 |
|
|
}
|
628 |
|
|
|
629 |
|
|
static struct workqueue_struct *sbp2_wq;
|
630 |
|
|
|
631 |
|
|
static void sbp2_reconnect(struct work_struct *work);
|
632 |
|
|
|
633 |
|
|
static void sbp2_login(struct work_struct *work)
|
634 |
|
|
{
|
635 |
|
|
struct sbp2_logical_unit *lu =
|
636 |
|
|
container_of(work, struct sbp2_logical_unit, work.work);
|
637 |
|
|
struct Scsi_Host *shost =
|
638 |
|
|
container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
|
639 |
|
|
struct scsi_device *sdev;
|
640 |
|
|
struct scsi_lun eight_bytes_lun;
|
641 |
|
|
struct fw_unit *unit = lu->tgt->unit;
|
642 |
|
|
struct fw_device *device = fw_device(unit->device.parent);
|
643 |
|
|
struct sbp2_login_response response;
|
644 |
|
|
int generation, node_id, local_node_id;
|
645 |
|
|
|
646 |
|
|
generation = device->card->generation;
|
647 |
|
|
node_id = device->node->node_id;
|
648 |
|
|
local_node_id = device->card->local_node->node_id;
|
649 |
|
|
|
650 |
|
|
if (sbp2_send_management_orb(lu, node_id, generation,
|
651 |
|
|
SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
|
652 |
|
|
if (lu->retries++ < 5) {
|
653 |
|
|
if (queue_delayed_work(sbp2_wq, &lu->work,
|
654 |
|
|
DIV_ROUND_UP(HZ, 5)))
|
655 |
|
|
kref_get(&lu->tgt->kref);
|
656 |
|
|
} else {
|
657 |
|
|
fw_error("failed to login to %s LUN %04x\n",
|
658 |
|
|
unit->device.bus_id, lu->lun);
|
659 |
|
|
}
|
660 |
|
|
kref_put(&lu->tgt->kref, sbp2_release_target);
|
661 |
|
|
return;
|
662 |
|
|
}
|
663 |
|
|
|
664 |
|
|
lu->generation = generation;
|
665 |
|
|
lu->tgt->node_id = node_id;
|
666 |
|
|
lu->tgt->address_high = local_node_id << 16;
|
667 |
|
|
|
668 |
|
|
/* Get command block agent offset and login id. */
|
669 |
|
|
lu->command_block_agent_address =
|
670 |
|
|
((u64) (response.command_block_agent.high & 0xffff) << 32) |
|
671 |
|
|
response.command_block_agent.low;
|
672 |
|
|
lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
|
673 |
|
|
|
674 |
|
|
fw_notify("logged in to %s LUN %04x (%d retries)\n",
|
675 |
|
|
unit->device.bus_id, lu->lun, lu->retries);
|
676 |
|
|
|
677 |
|
|
#if 0
|
678 |
|
|
/* FIXME: The linux1394 sbp2 does this last step. */
|
679 |
|
|
sbp2_set_busy_timeout(scsi_id);
|
680 |
|
|
#endif
|
681 |
|
|
|
682 |
|
|
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
|
683 |
|
|
sbp2_agent_reset(lu);
|
684 |
|
|
|
685 |
|
|
memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
|
686 |
|
|
eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
|
687 |
|
|
eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
|
688 |
|
|
|
689 |
|
|
sdev = __scsi_add_device(shost, 0, 0,
|
690 |
|
|
scsilun_to_int(&eight_bytes_lun), lu);
|
691 |
|
|
if (IS_ERR(sdev)) {
|
692 |
|
|
sbp2_send_management_orb(lu, node_id, generation,
|
693 |
|
|
SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
|
694 |
|
|
/*
|
695 |
|
|
* Set this back to sbp2_login so we fall back and
|
696 |
|
|
* retry login on bus reset.
|
697 |
|
|
*/
|
698 |
|
|
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
|
699 |
|
|
} else {
|
700 |
|
|
lu->sdev = sdev;
|
701 |
|
|
scsi_device_put(sdev);
|
702 |
|
|
}
|
703 |
|
|
kref_put(&lu->tgt->kref, sbp2_release_target);
|
704 |
|
|
}
|
705 |
|
|
|
706 |
|
|
static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
|
707 |
|
|
{
|
708 |
|
|
struct sbp2_logical_unit *lu;
|
709 |
|
|
|
710 |
|
|
lu = kmalloc(sizeof(*lu), GFP_KERNEL);
|
711 |
|
|
if (!lu)
|
712 |
|
|
return -ENOMEM;
|
713 |
|
|
|
714 |
|
|
lu->address_handler.length = 0x100;
|
715 |
|
|
lu->address_handler.address_callback = sbp2_status_write;
|
716 |
|
|
lu->address_handler.callback_data = lu;
|
717 |
|
|
|
718 |
|
|
if (fw_core_add_address_handler(&lu->address_handler,
|
719 |
|
|
&fw_high_memory_region) < 0) {
|
720 |
|
|
kfree(lu);
|
721 |
|
|
return -ENOMEM;
|
722 |
|
|
}
|
723 |
|
|
|
724 |
|
|
lu->tgt = tgt;
|
725 |
|
|
lu->sdev = NULL;
|
726 |
|
|
lu->lun = lun_entry & 0xffff;
|
727 |
|
|
lu->retries = 0;
|
728 |
|
|
INIT_LIST_HEAD(&lu->orb_list);
|
729 |
|
|
INIT_DELAYED_WORK(&lu->work, sbp2_login);
|
730 |
|
|
|
731 |
|
|
list_add_tail(&lu->link, &tgt->lu_list);
|
732 |
|
|
return 0;
|
733 |
|
|
}
|
734 |
|
|
|
735 |
|
|
static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory)
|
736 |
|
|
{
|
737 |
|
|
struct fw_csr_iterator ci;
|
738 |
|
|
int key, value;
|
739 |
|
|
|
740 |
|
|
fw_csr_iterator_init(&ci, directory);
|
741 |
|
|
while (fw_csr_iterator_next(&ci, &key, &value))
|
742 |
|
|
if (key == SBP2_CSR_LOGICAL_UNIT_NUMBER &&
|
743 |
|
|
sbp2_add_logical_unit(tgt, value) < 0)
|
744 |
|
|
return -ENOMEM;
|
745 |
|
|
return 0;
|
746 |
|
|
}
|
747 |
|
|
|
748 |
|
|
static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
|
749 |
|
|
u32 *model, u32 *firmware_revision)
|
750 |
|
|
{
|
751 |
|
|
struct fw_csr_iterator ci;
|
752 |
|
|
int key, value;
|
753 |
|
|
|
754 |
|
|
fw_csr_iterator_init(&ci, directory);
|
755 |
|
|
while (fw_csr_iterator_next(&ci, &key, &value)) {
|
756 |
|
|
switch (key) {
|
757 |
|
|
|
758 |
|
|
case CSR_DEPENDENT_INFO | CSR_OFFSET:
|
759 |
|
|
tgt->management_agent_address =
|
760 |
|
|
CSR_REGISTER_BASE + 4 * value;
|
761 |
|
|
break;
|
762 |
|
|
|
763 |
|
|
case CSR_DIRECTORY_ID:
|
764 |
|
|
tgt->directory_id = value;
|
765 |
|
|
break;
|
766 |
|
|
|
767 |
|
|
case CSR_MODEL:
|
768 |
|
|
*model = value;
|
769 |
|
|
break;
|
770 |
|
|
|
771 |
|
|
case SBP2_CSR_FIRMWARE_REVISION:
|
772 |
|
|
*firmware_revision = value;
|
773 |
|
|
break;
|
774 |
|
|
|
775 |
|
|
case SBP2_CSR_LOGICAL_UNIT_NUMBER:
|
776 |
|
|
if (sbp2_add_logical_unit(tgt, value) < 0)
|
777 |
|
|
return -ENOMEM;
|
778 |
|
|
break;
|
779 |
|
|
|
780 |
|
|
case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
|
781 |
|
|
if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
|
782 |
|
|
return -ENOMEM;
|
783 |
|
|
break;
|
784 |
|
|
}
|
785 |
|
|
}
|
786 |
|
|
return 0;
|
787 |
|
|
}
|
788 |
|
|
|
789 |
|
|
static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
|
790 |
|
|
u32 firmware_revision)
|
791 |
|
|
{
|
792 |
|
|
int i;
|
793 |
|
|
unsigned w = sbp2_param_workarounds;
|
794 |
|
|
|
795 |
|
|
if (w)
|
796 |
|
|
fw_notify("Please notify linux1394-devel@lists.sourceforge.net "
|
797 |
|
|
"if you need the workarounds parameter for %s\n",
|
798 |
|
|
tgt->unit->device.bus_id);
|
799 |
|
|
|
800 |
|
|
if (w & SBP2_WORKAROUND_OVERRIDE)
|
801 |
|
|
goto out;
|
802 |
|
|
|
803 |
|
|
for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
|
804 |
|
|
|
805 |
|
|
if (sbp2_workarounds_table[i].firmware_revision !=
|
806 |
|
|
(firmware_revision & 0xffffff00))
|
807 |
|
|
continue;
|
808 |
|
|
|
809 |
|
|
if (sbp2_workarounds_table[i].model != model &&
|
810 |
|
|
sbp2_workarounds_table[i].model != ~0)
|
811 |
|
|
continue;
|
812 |
|
|
|
813 |
|
|
w |= sbp2_workarounds_table[i].workarounds;
|
814 |
|
|
break;
|
815 |
|
|
}
|
816 |
|
|
out:
|
817 |
|
|
if (w)
|
818 |
|
|
fw_notify("Workarounds for %s: 0x%x "
|
819 |
|
|
"(firmware_revision 0x%06x, model_id 0x%06x)\n",
|
820 |
|
|
tgt->unit->device.bus_id,
|
821 |
|
|
w, firmware_revision, model);
|
822 |
|
|
tgt->workarounds = w;
|
823 |
|
|
}
|
824 |
|
|
|
825 |
|
|
static struct scsi_host_template scsi_driver_template;
|
826 |
|
|
|
827 |
|
|
static int sbp2_probe(struct device *dev)
|
828 |
|
|
{
|
829 |
|
|
struct fw_unit *unit = fw_unit(dev);
|
830 |
|
|
struct fw_device *device = fw_device(unit->device.parent);
|
831 |
|
|
struct sbp2_target *tgt;
|
832 |
|
|
struct sbp2_logical_unit *lu;
|
833 |
|
|
struct Scsi_Host *shost;
|
834 |
|
|
u32 model, firmware_revision;
|
835 |
|
|
|
836 |
|
|
shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
|
837 |
|
|
if (shost == NULL)
|
838 |
|
|
return -ENOMEM;
|
839 |
|
|
|
840 |
|
|
tgt = (struct sbp2_target *)shost->hostdata;
|
841 |
|
|
unit->device.driver_data = tgt;
|
842 |
|
|
tgt->unit = unit;
|
843 |
|
|
kref_init(&tgt->kref);
|
844 |
|
|
INIT_LIST_HEAD(&tgt->lu_list);
|
845 |
|
|
|
846 |
|
|
if (fw_device_enable_phys_dma(device) < 0)
|
847 |
|
|
goto fail_shost_put;
|
848 |
|
|
|
849 |
|
|
if (scsi_add_host(shost, &unit->device) < 0)
|
850 |
|
|
goto fail_shost_put;
|
851 |
|
|
|
852 |
|
|
/* Initialize to values that won't match anything in our table. */
|
853 |
|
|
firmware_revision = 0xff000000;
|
854 |
|
|
model = 0xff000000;
|
855 |
|
|
|
856 |
|
|
/* implicit directory ID */
|
857 |
|
|
tgt->directory_id = ((unit->directory - device->config_rom) * 4
|
858 |
|
|
+ CSR_CONFIG_ROM) & 0xffffff;
|
859 |
|
|
|
860 |
|
|
if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
|
861 |
|
|
&firmware_revision) < 0)
|
862 |
|
|
goto fail_tgt_put;
|
863 |
|
|
|
864 |
|
|
sbp2_init_workarounds(tgt, model, firmware_revision);
|
865 |
|
|
|
866 |
|
|
get_device(&unit->device);
|
867 |
|
|
|
868 |
|
|
/*
|
869 |
|
|
* We schedule work to do the login so we can easily
|
870 |
|
|
* reschedule retries. Always get the ref before scheduling
|
871 |
|
|
* work.
|
872 |
|
|
*/
|
873 |
|
|
list_for_each_entry(lu, &tgt->lu_list, link)
|
874 |
|
|
if (queue_delayed_work(sbp2_wq, &lu->work, 0))
|
875 |
|
|
kref_get(&tgt->kref);
|
876 |
|
|
return 0;
|
877 |
|
|
|
878 |
|
|
fail_tgt_put:
|
879 |
|
|
kref_put(&tgt->kref, sbp2_release_target);
|
880 |
|
|
return -ENOMEM;
|
881 |
|
|
|
882 |
|
|
fail_shost_put:
|
883 |
|
|
scsi_host_put(shost);
|
884 |
|
|
return -ENOMEM;
|
885 |
|
|
}
|
886 |
|
|
|
887 |
|
|
static int sbp2_remove(struct device *dev)
|
888 |
|
|
{
|
889 |
|
|
struct fw_unit *unit = fw_unit(dev);
|
890 |
|
|
struct sbp2_target *tgt = unit->device.driver_data;
|
891 |
|
|
|
892 |
|
|
kref_put(&tgt->kref, sbp2_release_target);
|
893 |
|
|
return 0;
|
894 |
|
|
}
|
895 |
|
|
|
896 |
|
|
static void sbp2_reconnect(struct work_struct *work)
|
897 |
|
|
{
|
898 |
|
|
struct sbp2_logical_unit *lu =
|
899 |
|
|
container_of(work, struct sbp2_logical_unit, work.work);
|
900 |
|
|
struct fw_unit *unit = lu->tgt->unit;
|
901 |
|
|
struct fw_device *device = fw_device(unit->device.parent);
|
902 |
|
|
int generation, node_id, local_node_id;
|
903 |
|
|
|
904 |
|
|
generation = device->card->generation;
|
905 |
|
|
node_id = device->node->node_id;
|
906 |
|
|
local_node_id = device->card->local_node->node_id;
|
907 |
|
|
|
908 |
|
|
if (sbp2_send_management_orb(lu, node_id, generation,
|
909 |
|
|
SBP2_RECONNECT_REQUEST,
|
910 |
|
|
lu->login_id, NULL) < 0) {
|
911 |
|
|
if (lu->retries++ >= 5) {
|
912 |
|
|
fw_error("failed to reconnect to %s\n",
|
913 |
|
|
unit->device.bus_id);
|
914 |
|
|
/* Fall back and try to log in again. */
|
915 |
|
|
lu->retries = 0;
|
916 |
|
|
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
|
917 |
|
|
}
|
918 |
|
|
if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5)))
|
919 |
|
|
kref_get(&lu->tgt->kref);
|
920 |
|
|
kref_put(&lu->tgt->kref, sbp2_release_target);
|
921 |
|
|
return;
|
922 |
|
|
}
|
923 |
|
|
|
924 |
|
|
lu->generation = generation;
|
925 |
|
|
lu->tgt->node_id = node_id;
|
926 |
|
|
lu->tgt->address_high = local_node_id << 16;
|
927 |
|
|
|
928 |
|
|
fw_notify("reconnected to %s LUN %04x (%d retries)\n",
|
929 |
|
|
unit->device.bus_id, lu->lun, lu->retries);
|
930 |
|
|
|
931 |
|
|
sbp2_agent_reset(lu);
|
932 |
|
|
sbp2_cancel_orbs(lu);
|
933 |
|
|
|
934 |
|
|
kref_put(&lu->tgt->kref, sbp2_release_target);
|
935 |
|
|
}
|
936 |
|
|
|
937 |
|
|
static void sbp2_update(struct fw_unit *unit)
|
938 |
|
|
{
|
939 |
|
|
struct sbp2_target *tgt = unit->device.driver_data;
|
940 |
|
|
struct sbp2_logical_unit *lu;
|
941 |
|
|
|
942 |
|
|
fw_device_enable_phys_dma(fw_device(unit->device.parent));
|
943 |
|
|
|
944 |
|
|
/*
|
945 |
|
|
* Fw-core serializes sbp2_update() against sbp2_remove().
|
946 |
|
|
* Iteration over tgt->lu_list is therefore safe here.
|
947 |
|
|
*/
|
948 |
|
|
list_for_each_entry(lu, &tgt->lu_list, link) {
|
949 |
|
|
lu->retries = 0;
|
950 |
|
|
if (queue_delayed_work(sbp2_wq, &lu->work, 0))
|
951 |
|
|
kref_get(&tgt->kref);
|
952 |
|
|
}
|
953 |
|
|
}
|
954 |
|
|
|
955 |
|
|
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
|
956 |
|
|
#define SBP2_SW_VERSION_ENTRY 0x00010483
|
957 |
|
|
|
958 |
|
|
static const struct fw_device_id sbp2_id_table[] = {
|
959 |
|
|
{
|
960 |
|
|
.match_flags = FW_MATCH_SPECIFIER_ID | FW_MATCH_VERSION,
|
961 |
|
|
.specifier_id = SBP2_UNIT_SPEC_ID_ENTRY,
|
962 |
|
|
.version = SBP2_SW_VERSION_ENTRY,
|
963 |
|
|
},
|
964 |
|
|
{ }
|
965 |
|
|
};
|
966 |
|
|
|
967 |
|
|
static struct fw_driver sbp2_driver = {
|
968 |
|
|
.driver = {
|
969 |
|
|
.owner = THIS_MODULE,
|
970 |
|
|
.name = sbp2_driver_name,
|
971 |
|
|
.bus = &fw_bus_type,
|
972 |
|
|
.probe = sbp2_probe,
|
973 |
|
|
.remove = sbp2_remove,
|
974 |
|
|
},
|
975 |
|
|
.update = sbp2_update,
|
976 |
|
|
.id_table = sbp2_id_table,
|
977 |
|
|
};
|
978 |
|
|
|
979 |
|
|
static unsigned int
|
980 |
|
|
sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
|
981 |
|
|
{
|
982 |
|
|
int sam_status;
|
983 |
|
|
|
984 |
|
|
sense_data[0] = 0x70;
|
985 |
|
|
sense_data[1] = 0x0;
|
986 |
|
|
sense_data[2] = sbp2_status[1];
|
987 |
|
|
sense_data[3] = sbp2_status[4];
|
988 |
|
|
sense_data[4] = sbp2_status[5];
|
989 |
|
|
sense_data[5] = sbp2_status[6];
|
990 |
|
|
sense_data[6] = sbp2_status[7];
|
991 |
|
|
sense_data[7] = 10;
|
992 |
|
|
sense_data[8] = sbp2_status[8];
|
993 |
|
|
sense_data[9] = sbp2_status[9];
|
994 |
|
|
sense_data[10] = sbp2_status[10];
|
995 |
|
|
sense_data[11] = sbp2_status[11];
|
996 |
|
|
sense_data[12] = sbp2_status[2];
|
997 |
|
|
sense_data[13] = sbp2_status[3];
|
998 |
|
|
sense_data[14] = sbp2_status[12];
|
999 |
|
|
sense_data[15] = sbp2_status[13];
|
1000 |
|
|
|
1001 |
|
|
sam_status = sbp2_status[0] & 0x3f;
|
1002 |
|
|
|
1003 |
|
|
switch (sam_status) {
|
1004 |
|
|
case SAM_STAT_GOOD:
|
1005 |
|
|
case SAM_STAT_CHECK_CONDITION:
|
1006 |
|
|
case SAM_STAT_CONDITION_MET:
|
1007 |
|
|
case SAM_STAT_BUSY:
|
1008 |
|
|
case SAM_STAT_RESERVATION_CONFLICT:
|
1009 |
|
|
case SAM_STAT_COMMAND_TERMINATED:
|
1010 |
|
|
return DID_OK << 16 | sam_status;
|
1011 |
|
|
|
1012 |
|
|
default:
|
1013 |
|
|
return DID_ERROR << 16;
|
1014 |
|
|
}
|
1015 |
|
|
}
|
1016 |
|
|
|
1017 |
|
|
static void
|
1018 |
|
|
complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
|
1019 |
|
|
{
|
1020 |
|
|
struct sbp2_command_orb *orb =
|
1021 |
|
|
container_of(base_orb, struct sbp2_command_orb, base);
|
1022 |
|
|
struct fw_device *device = fw_device(orb->lu->tgt->unit->device.parent);
|
1023 |
|
|
int result;
|
1024 |
|
|
|
1025 |
|
|
if (status != NULL) {
|
1026 |
|
|
if (STATUS_GET_DEAD(*status))
|
1027 |
|
|
sbp2_agent_reset(orb->lu);
|
1028 |
|
|
|
1029 |
|
|
switch (STATUS_GET_RESPONSE(*status)) {
|
1030 |
|
|
case SBP2_STATUS_REQUEST_COMPLETE:
|
1031 |
|
|
result = DID_OK << 16;
|
1032 |
|
|
break;
|
1033 |
|
|
case SBP2_STATUS_TRANSPORT_FAILURE:
|
1034 |
|
|
result = DID_BUS_BUSY << 16;
|
1035 |
|
|
break;
|
1036 |
|
|
case SBP2_STATUS_ILLEGAL_REQUEST:
|
1037 |
|
|
case SBP2_STATUS_VENDOR_DEPENDENT:
|
1038 |
|
|
default:
|
1039 |
|
|
result = DID_ERROR << 16;
|
1040 |
|
|
break;
|
1041 |
|
|
}
|
1042 |
|
|
|
1043 |
|
|
if (result == DID_OK << 16 && STATUS_GET_LEN(*status) > 1)
|
1044 |
|
|
result = sbp2_status_to_sense_data(STATUS_GET_DATA(*status),
|
1045 |
|
|
orb->cmd->sense_buffer);
|
1046 |
|
|
} else {
|
1047 |
|
|
/*
|
1048 |
|
|
* If the orb completes with status == NULL, something
|
1049 |
|
|
* went wrong, typically a bus reset happened mid-orb
|
1050 |
|
|
* or when sending the write (less likely).
|
1051 |
|
|
*/
|
1052 |
|
|
result = DID_BUS_BUSY << 16;
|
1053 |
|
|
}
|
1054 |
|
|
|
1055 |
|
|
dma_unmap_single(device->card->device, orb->base.request_bus,
|
1056 |
|
|
sizeof(orb->request), DMA_TO_DEVICE);
|
1057 |
|
|
|
1058 |
|
|
if (scsi_sg_count(orb->cmd) > 0)
|
1059 |
|
|
dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
|
1060 |
|
|
scsi_sg_count(orb->cmd),
|
1061 |
|
|
orb->cmd->sc_data_direction);
|
1062 |
|
|
|
1063 |
|
|
if (orb->page_table_bus != 0)
|
1064 |
|
|
dma_unmap_single(device->card->device, orb->page_table_bus,
|
1065 |
|
|
sizeof(orb->page_table), DMA_TO_DEVICE);
|
1066 |
|
|
|
1067 |
|
|
orb->cmd->result = result;
|
1068 |
|
|
orb->done(orb->cmd);
|
1069 |
|
|
}
|
1070 |
|
|
|
1071 |
|
|
static int
|
1072 |
|
|
sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
|
1073 |
|
|
struct sbp2_logical_unit *lu)
|
1074 |
|
|
{
|
1075 |
|
|
struct scatterlist *sg;
|
1076 |
|
|
int sg_len, l, i, j, count;
|
1077 |
|
|
dma_addr_t sg_addr;
|
1078 |
|
|
|
1079 |
|
|
sg = scsi_sglist(orb->cmd);
|
1080 |
|
|
count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
|
1081 |
|
|
orb->cmd->sc_data_direction);
|
1082 |
|
|
if (count == 0)
|
1083 |
|
|
goto fail;
|
1084 |
|
|
|
1085 |
|
|
/*
|
1086 |
|
|
* Handle the special case where there is only one element in
|
1087 |
|
|
* the scatter list by converting it to an immediate block
|
1088 |
|
|
* request. This is also a workaround for broken devices such
|
1089 |
|
|
* as the second generation iPod which doesn't support page
|
1090 |
|
|
* tables.
|
1091 |
|
|
*/
|
1092 |
|
|
if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
|
1093 |
|
|
orb->request.data_descriptor.high = lu->tgt->address_high;
|
1094 |
|
|
orb->request.data_descriptor.low = sg_dma_address(sg);
|
1095 |
|
|
orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
|
1096 |
|
|
return 0;
|
1097 |
|
|
}
|
1098 |
|
|
|
1099 |
|
|
/*
|
1100 |
|
|
* Convert the scatterlist to an sbp2 page table. If any
|
1101 |
|
|
* scatterlist entries are too big for sbp2, we split them as we
|
1102 |
|
|
* go. Even if we ask the block I/O layer to not give us sg
|
1103 |
|
|
* elements larger than 65535 bytes, some IOMMUs may merge sg elements
|
1104 |
|
|
* during DMA mapping, and Linux currently doesn't prevent this.
|
1105 |
|
|
*/
|
1106 |
|
|
for (i = 0, j = 0; i < count; i++) {
|
1107 |
|
|
sg_len = sg_dma_len(sg + i);
|
1108 |
|
|
sg_addr = sg_dma_address(sg + i);
|
1109 |
|
|
while (sg_len) {
|
1110 |
|
|
/* FIXME: This won't get us out of the pinch. */
|
1111 |
|
|
if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
|
1112 |
|
|
fw_error("page table overflow\n");
|
1113 |
|
|
goto fail_page_table;
|
1114 |
|
|
}
|
1115 |
|
|
l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
|
1116 |
|
|
orb->page_table[j].low = sg_addr;
|
1117 |
|
|
orb->page_table[j].high = (l << 16);
|
1118 |
|
|
sg_addr += l;
|
1119 |
|
|
sg_len -= l;
|
1120 |
|
|
j++;
|
1121 |
|
|
}
|
1122 |
|
|
}
|
1123 |
|
|
|
1124 |
|
|
fw_memcpy_to_be32(orb->page_table, orb->page_table,
|
1125 |
|
|
sizeof(orb->page_table[0]) * j);
|
1126 |
|
|
orb->page_table_bus =
|
1127 |
|
|
dma_map_single(device->card->device, orb->page_table,
|
1128 |
|
|
sizeof(orb->page_table), DMA_TO_DEVICE);
|
1129 |
|
|
if (dma_mapping_error(orb->page_table_bus))
|
1130 |
|
|
goto fail_page_table;
|
1131 |
|
|
|
1132 |
|
|
/*
|
1133 |
|
|
* The data_descriptor pointer is the one case where we need
|
1134 |
|
|
* to fill in the node ID part of the address. All other
|
1135 |
|
|
* pointers assume that the data referenced reside on the
|
1136 |
|
|
* initiator (i.e. us), but data_descriptor can refer to data
|
1137 |
|
|
* on other nodes so we need to put our ID in descriptor.high.
|
1138 |
|
|
*/
|
1139 |
|
|
orb->request.data_descriptor.high = lu->tgt->address_high;
|
1140 |
|
|
orb->request.data_descriptor.low = orb->page_table_bus;
|
1141 |
|
|
orb->request.misc |=
|
1142 |
|
|
COMMAND_ORB_PAGE_TABLE_PRESENT |
|
1143 |
|
|
COMMAND_ORB_DATA_SIZE(j);
|
1144 |
|
|
|
1145 |
|
|
return 0;
|
1146 |
|
|
|
1147 |
|
|
fail_page_table:
|
1148 |
|
|
dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
|
1149 |
|
|
orb->cmd->sc_data_direction);
|
1150 |
|
|
fail:
|
1151 |
|
|
return -ENOMEM;
|
1152 |
|
|
}
|
1153 |
|
|
|
1154 |
|
|
/* SCSI stack integration */
|
1155 |
|
|
|
1156 |
|
|
static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
|
1157 |
|
|
{
|
1158 |
|
|
struct sbp2_logical_unit *lu = cmd->device->hostdata;
|
1159 |
|
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
1160 |
|
|
struct sbp2_command_orb *orb;
|
1161 |
|
|
unsigned max_payload;
|
1162 |
|
|
int retval = SCSI_MLQUEUE_HOST_BUSY;
|
1163 |
|
|
|
1164 |
|
|
/*
|
1165 |
|
|
* Bidirectional commands are not yet implemented, and unknown
|
1166 |
|
|
* transfer direction not handled.
|
1167 |
|
|
*/
|
1168 |
|
|
if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
|
1169 |
|
|
fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
|
1170 |
|
|
cmd->result = DID_ERROR << 16;
|
1171 |
|
|
done(cmd);
|
1172 |
|
|
return 0;
|
1173 |
|
|
}
|
1174 |
|
|
|
1175 |
|
|
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
|
1176 |
|
|
if (orb == NULL) {
|
1177 |
|
|
fw_notify("failed to alloc orb\n");
|
1178 |
|
|
return SCSI_MLQUEUE_HOST_BUSY;
|
1179 |
|
|
}
|
1180 |
|
|
|
1181 |
|
|
/* Initialize rcode to something not RCODE_COMPLETE. */
|
1182 |
|
|
orb->base.rcode = -1;
|
1183 |
|
|
kref_init(&orb->base.kref);
|
1184 |
|
|
|
1185 |
|
|
orb->lu = lu;
|
1186 |
|
|
orb->done = done;
|
1187 |
|
|
orb->cmd = cmd;
|
1188 |
|
|
|
1189 |
|
|
orb->request.next.high = SBP2_ORB_NULL;
|
1190 |
|
|
orb->request.next.low = 0x0;
|
1191 |
|
|
/*
|
1192 |
|
|
* At speed 100 we can do 512 bytes per packet, at speed 200,
|
1193 |
|
|
* 1024 bytes per packet etc. The SBP-2 max_payload field
|
1194 |
|
|
* specifies the max payload size as 2 ^ (max_payload + 2), so
|
1195 |
|
|
* if we set this to max_speed + 7, we get the right value.
|
1196 |
|
|
*/
|
1197 |
|
|
max_payload = min(device->max_speed + 7,
|
1198 |
|
|
device->card->max_receive - 1);
|
1199 |
|
|
orb->request.misc =
|
1200 |
|
|
COMMAND_ORB_MAX_PAYLOAD(max_payload) |
|
1201 |
|
|
COMMAND_ORB_SPEED(device->max_speed) |
|
1202 |
|
|
COMMAND_ORB_NOTIFY;
|
1203 |
|
|
|
1204 |
|
|
if (cmd->sc_data_direction == DMA_FROM_DEVICE)
|
1205 |
|
|
orb->request.misc |=
|
1206 |
|
|
COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA);
|
1207 |
|
|
else if (cmd->sc_data_direction == DMA_TO_DEVICE)
|
1208 |
|
|
orb->request.misc |=
|
1209 |
|
|
COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
|
1210 |
|
|
|
1211 |
|
|
if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
|
1212 |
|
|
goto out;
|
1213 |
|
|
|
1214 |
|
|
fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
|
1215 |
|
|
|
1216 |
|
|
memset(orb->request.command_block,
|
1217 |
|
|
0, sizeof(orb->request.command_block));
|
1218 |
|
|
memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
|
1219 |
|
|
|
1220 |
|
|
orb->base.callback = complete_command_orb;
|
1221 |
|
|
orb->base.request_bus =
|
1222 |
|
|
dma_map_single(device->card->device, &orb->request,
|
1223 |
|
|
sizeof(orb->request), DMA_TO_DEVICE);
|
1224 |
|
|
if (dma_mapping_error(orb->base.request_bus))
|
1225 |
|
|
goto out;
|
1226 |
|
|
|
1227 |
|
|
sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
|
1228 |
|
|
lu->command_block_agent_address + SBP2_ORB_POINTER);
|
1229 |
|
|
retval = 0;
|
1230 |
|
|
out:
|
1231 |
|
|
kref_put(&orb->base.kref, free_orb);
|
1232 |
|
|
return retval;
|
1233 |
|
|
}
|
1234 |
|
|
|
1235 |
|
|
static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
|
1236 |
|
|
{
|
1237 |
|
|
struct sbp2_logical_unit *lu = sdev->hostdata;
|
1238 |
|
|
|
1239 |
|
|
sdev->allow_restart = 1;
|
1240 |
|
|
|
1241 |
|
|
if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
|
1242 |
|
|
sdev->inquiry_len = 36;
|
1243 |
|
|
|
1244 |
|
|
return 0;
|
1245 |
|
|
}
|
1246 |
|
|
|
1247 |
|
|
static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
|
1248 |
|
|
{
|
1249 |
|
|
struct sbp2_logical_unit *lu = sdev->hostdata;
|
1250 |
|
|
|
1251 |
|
|
sdev->use_10_for_rw = 1;
|
1252 |
|
|
|
1253 |
|
|
if (sdev->type == TYPE_ROM)
|
1254 |
|
|
sdev->use_10_for_ms = 1;
|
1255 |
|
|
|
1256 |
|
|
if (sdev->type == TYPE_DISK &&
|
1257 |
|
|
lu->tgt->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
|
1258 |
|
|
sdev->skip_ms_page_8 = 1;
|
1259 |
|
|
|
1260 |
|
|
if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
|
1261 |
|
|
sdev->fix_capacity = 1;
|
1262 |
|
|
|
1263 |
|
|
if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
|
1264 |
|
|
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
|
1265 |
|
|
|
1266 |
|
|
return 0;
|
1267 |
|
|
}
|
1268 |
|
|
|
1269 |
|
|
/*
|
1270 |
|
|
* Called by scsi stack when something has really gone wrong. Usually
|
1271 |
|
|
* called when a command has timed-out for some reason.
|
1272 |
|
|
*/
|
1273 |
|
|
static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
|
1274 |
|
|
{
|
1275 |
|
|
struct sbp2_logical_unit *lu = cmd->device->hostdata;
|
1276 |
|
|
|
1277 |
|
|
fw_notify("sbp2_scsi_abort\n");
|
1278 |
|
|
sbp2_agent_reset(lu);
|
1279 |
|
|
sbp2_cancel_orbs(lu);
|
1280 |
|
|
|
1281 |
|
|
return SUCCESS;
|
1282 |
|
|
}
|
1283 |
|
|
|
1284 |
|
|
/*
|
1285 |
|
|
* Format of /sys/bus/scsi/devices/.../ieee1394_id:
|
1286 |
|
|
* u64 EUI-64 : u24 directory_ID : u16 LUN (all printed in hexadecimal)
|
1287 |
|
|
*
|
1288 |
|
|
* This is the concatenation of target port identifier and logical unit
|
1289 |
|
|
* identifier as per SAM-2...SAM-4 annex A.
|
1290 |
|
|
*/
|
1291 |
|
|
static ssize_t
|
1292 |
|
|
sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
|
1293 |
|
|
char *buf)
|
1294 |
|
|
{
|
1295 |
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
1296 |
|
|
struct sbp2_logical_unit *lu;
|
1297 |
|
|
struct fw_device *device;
|
1298 |
|
|
|
1299 |
|
|
if (!sdev)
|
1300 |
|
|
return 0;
|
1301 |
|
|
|
1302 |
|
|
lu = sdev->hostdata;
|
1303 |
|
|
device = fw_device(lu->tgt->unit->device.parent);
|
1304 |
|
|
|
1305 |
|
|
return sprintf(buf, "%08x%08x:%06x:%04x\n",
|
1306 |
|
|
device->config_rom[3], device->config_rom[4],
|
1307 |
|
|
lu->tgt->directory_id, lu->lun);
|
1308 |
|
|
}
|
1309 |
|
|
|
1310 |
|
|
static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
|
1311 |
|
|
|
1312 |
|
|
static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
|
1313 |
|
|
&dev_attr_ieee1394_id,
|
1314 |
|
|
NULL
|
1315 |
|
|
};
|
1316 |
|
|
|
1317 |
|
|
static struct scsi_host_template scsi_driver_template = {
|
1318 |
|
|
.module = THIS_MODULE,
|
1319 |
|
|
.name = "SBP-2 IEEE-1394",
|
1320 |
|
|
.proc_name = sbp2_driver_name,
|
1321 |
|
|
.queuecommand = sbp2_scsi_queuecommand,
|
1322 |
|
|
.slave_alloc = sbp2_scsi_slave_alloc,
|
1323 |
|
|
.slave_configure = sbp2_scsi_slave_configure,
|
1324 |
|
|
.eh_abort_handler = sbp2_scsi_abort,
|
1325 |
|
|
.this_id = -1,
|
1326 |
|
|
.sg_tablesize = SG_ALL,
|
1327 |
|
|
.use_clustering = ENABLE_CLUSTERING,
|
1328 |
|
|
.cmd_per_lun = 1,
|
1329 |
|
|
.can_queue = 1,
|
1330 |
|
|
.sdev_attrs = sbp2_scsi_sysfs_attrs,
|
1331 |
|
|
};
|
1332 |
|
|
|
1333 |
|
|
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
|
1334 |
|
|
MODULE_DESCRIPTION("SCSI over IEEE1394");
|
1335 |
|
|
MODULE_LICENSE("GPL");
|
1336 |
|
|
MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
|
1337 |
|
|
|
1338 |
|
|
/* Provide a module alias so root-on-sbp2 initrds don't break. */
|
1339 |
|
|
#ifndef CONFIG_IEEE1394_SBP2_MODULE
|
1340 |
|
|
MODULE_ALIAS("sbp2");
|
1341 |
|
|
#endif
|
1342 |
|
|
|
1343 |
|
|
static int __init sbp2_init(void)
|
1344 |
|
|
{
|
1345 |
|
|
sbp2_wq = create_singlethread_workqueue(KBUILD_MODNAME);
|
1346 |
|
|
if (!sbp2_wq)
|
1347 |
|
|
return -ENOMEM;
|
1348 |
|
|
|
1349 |
|
|
return driver_register(&sbp2_driver.driver);
|
1350 |
|
|
}
|
1351 |
|
|
|
1352 |
|
|
static void __exit sbp2_cleanup(void)
|
1353 |
|
|
{
|
1354 |
|
|
driver_unregister(&sbp2_driver.driver);
|
1355 |
|
|
destroy_workqueue(sbp2_wq);
|
1356 |
|
|
}
|
1357 |
|
|
|
1358 |
|
|
module_init(sbp2_init);
|
1359 |
|
|
module_exit(sbp2_cleanup);
|