Print this page
4031 scsa1394 violates DDI scsi_pkt(9S) allocation rules
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/1394/targets/scsa1394/sbp2_driver.c
+++ new/usr/src/uts/common/io/1394/targets/scsa1394/sbp2_driver.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * 1394 mass storage SBP-2 driver routines
28 28 */
29 29
30 30 #include <sys/param.h>
31 31 #include <sys/errno.h>
32 32 #include <sys/cred.h>
33 33 #include <sys/conf.h>
34 34 #include <sys/modctl.h>
35 35 #include <sys/stat.h>
36 36 #include <sys/ddi.h>
37 37 #include <sys/sunddi.h>
38 38
39 39 #include <sys/1394/targets/scsa1394/impl.h>
40 40 #include <sys/1394/targets/scsa1394/cmd.h>
41 41 #include <sys/sbp2/bus.h>
42 42 #include <sys/sbp2/driver.h>
43 43
44 44 static void scsa1394_sbp2_detect_symbios(scsa1394_state_t *);
45 45 static void scsa1394_sbp2_worker_thread(void *);
46 46 static void scsa1394_sbp2_status_cb(void *, sbp2_task_t *);
47 47 static void scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *,
48 48 scsa1394_cmd_t *);
49 49 static void scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *,
50 50 scsa1394_cmd_t *);
51 51 static void scsa1394_sbp2_req_status(scsa1394_lun_t *);
52 52 static void scsa1394_sbp2_status_proc(scsa1394_lun_t *, scsa1394_cmd_t *,
53 53 scsa1394_status_t *);
54 54 static int scsa1394_sbp2_conv_status(scsa1394_cmd_t *,
55 55 scsa1394_status_t *);
56 56 static void scsa1394_sbp2_reset_proc(scsa1394_lun_t *, int,
57 57 scsa1394_cmd_t *);
58 58 static boolean_t scsa1394_sbp2_logged_in(scsa1394_lun_t *);
59 59
60 60 extern sbp2_bus_t scsa1394_sbp2_bus;
61 61
62 62 /* tunables */
63 63 uint_t scsa1394_sbp2_max_payload_sub = 2;
64 64 extern int scsa1394_symbios_size_max;
65 65 extern int scsa1394_symbios_page_size;
66 66 extern int scsa1394_wrka_symbios;
67 67
68 68 /* symbios workaround will be applied unless device is on this list */
69 69 scsa1394_bw_list_t scsa1394_sbp2_symbios_whitelist[] = {
70 70 { SCSA1394_BW_ONE, 0x0a27 }, /* Apple */
71 71 { SCSA1394_BW_ONE, 0xd04b } /* LaCie */
72 72 };
73 73
74 74 /*
75 75 *
76 76 * --- SBP-2 routines
77 77 *
78 78 */
79 79 int
80 80 scsa1394_sbp2_attach(scsa1394_state_t *sp)
81 81 {
82 82 sbp2_tgt_t *tp;
83 83 scsa1394_lun_t *lp;
84 84 int i;
85 85
86 86 /*
87 87 * target
88 88 */
89 89 if (sbp2_tgt_init(sp, &scsa1394_sbp2_bus, NLUNS_PER_TARGET,
90 90 &sp->s_tgt) != SBP2_SUCCESS) {
91 91 return (DDI_FAILURE);
92 92 }
93 93 tp = sp->s_tgt;
94 94
95 95 /*
96 96 * luns
97 97 */
98 98 sp->s_nluns = tp->t_nluns;
99 99 sp->s_lun = kmem_zalloc(sp->s_nluns * sizeof (scsa1394_lun_t),
100 100 KM_SLEEP);
101 101
102 102 for (i = 0; i < sp->s_nluns; i++) {
103 103 lp = &sp->s_lun[i];
104 104
105 105 mutex_init(&lp->l_mutex, NULL, MUTEX_DRIVER,
106 106 sp->s_attachinfo.iblock_cookie);
107 107
108 108 lp->l_rmb_orig = -1;
109 109 lp->l_lun = &tp->t_lun[i];
110 110 lp->l_sp = sp;
111 111 lp->l_lba_size = DEV_BSIZE;
112 112 }
113 113
114 114 scsa1394_sbp2_detect_symbios(sp);
115 115
116 116 return (DDI_SUCCESS);
117 117 }
118 118
119 119 void
120 120 scsa1394_sbp2_detach(scsa1394_state_t *sp)
121 121 {
122 122 int i;
123 123 scsa1394_lun_t *lp;
124 124
125 125 for (i = 0; i < sp->s_nluns; i++) {
126 126 lp = &sp->s_lun[i];
127 127 if (lp->l_sp != NULL) {
128 128 mutex_destroy(&lp->l_mutex);
129 129 }
130 130 }
131 131
132 132 kmem_free(sp->s_lun, sp->s_nluns * sizeof (scsa1394_lun_t));
133 133 sbp2_tgt_fini(sp->s_tgt);
134 134 }
135 135
136 136 static void
137 137 scsa1394_sbp2_detect_symbios(scsa1394_state_t *sp)
138 138 {
139 139 sbp2_cfgrom_ent_t *root = &sp->s_tgt->t_cfgrom.cr_root;
140 140 sbp2_cfgrom_ent_t *ent;
141 141 scsa1394_bw_list_t *wl;
142 142 int vid;
143 143 int i;
144 144
145 145
146 146 if (!scsa1394_wrka_symbios) {
147 147 sp->s_symbios = B_FALSE;
148 148 return;
149 149 } else {
150 150 sp->s_symbios = B_TRUE;
151 151 }
152 152
153 153 /* get device's vendor ID */
154 154 if ((ent = sbp2_cfgrom_ent_by_key(root, IEEE1212_IMMEDIATE_TYPE,
155 155 IEEE1212_MODULE_VENDOR_ID, 0)) == NULL) {
156 156 return;
157 157 }
158 158 vid = ent->ce_data.imm;
159 159
160 160 /* find a match in the whitelist */
161 161 for (i = 0; i < NELEM(scsa1394_sbp2_symbios_whitelist); i++) {
162 162 wl = &scsa1394_sbp2_symbios_whitelist[i];
163 163 if ((wl->vid_match == SCSA1394_BW_ONE) && (wl->vid == vid)) {
164 164 sp->s_symbios = B_FALSE;
165 165 break;
166 166 }
167 167 }
168 168 }
169 169
170 170
171 171 /*
172 172 * functional equivalent of ddi_rep_get32() with big endian access handle
173 173 */
174 174 static void
175 175 bcopy_swap32(uint32_t *from, uint32_t *to, int count)
176 176 {
177 177 int i;
178 178 uint32_t data;
179 179
180 180 ASSERT((uintptr_t)to % 4 == 0);
181 181
182 182 for (i = 0; i < count; i++) {
183 183 data = *from++;
184 184 *to++ = SBP2_SWAP32(data);
185 185 }
186 186 }
187 187
188 188 /*
189 189 * Build an inquiry for a given device that doesn't like inquiry commands.
190 190 */
191 191 void
192 192 scsa1394_sbp2_fake_inquiry(scsa1394_state_t *sp, struct scsi_inquiry *inq)
193 193 {
194 194 sbp2_cfgrom_ent_t *r = &sp->s_tgt->t_cfgrom.cr_root;
195 195 sbp2_cfgrom_ent_t *e, *eref, *evid;
196 196 int i, len;
197 197
198 198 bzero(inq, sizeof (struct scsi_inquiry));
199 199
200 200 inq->inq_dtype = DTYPE_DIRECT;
201 201 inq->inq_rmb = 1;
202 202 inq->inq_ansi = 2;
203 203 inq->inq_rdf = RDF_SCSI2;
204 204 inq->inq_len = sizeof (struct scsi_inquiry) - 4;
205 205
206 206 (void) memset(inq->inq_vid, ' ', sizeof (inq->inq_vid));
207 207 (void) memset(inq->inq_pid, ' ', sizeof (inq->inq_pid));
208 208 (void) memset(inq->inq_revision, ' ', sizeof (inq->inq_revision));
209 209
210 210 /*
211 211 * vid/pid/rev can be derived from Config ROM textual descriptors
212 212 */
213 213 for (i = 0; i < 256; i++) {
214 214 if ((e = sbp2_cfgrom_ent_by_key(r, IEEE1212_LEAF_TYPE,
215 215 IEEE1212_TEXTUAL_DESCRIPTOR, i)) == NULL) {
216 216 break;
217 217 }
218 218 eref = e->ce_ref;
219 219 if ((eref == NULL) || (eref->ce_len < 3) &&
220 220 (eref->ce_kt != IEEE1212_IMMEDIATE_TYPE)) {
221 221 continue;
222 222 }
223 223
224 224 len = e->ce_len - 2;
225 225 if (eref->ce_kv == IEEE1212_MODULE_VENDOR_ID) {
226 226 evid = e;
227 227 bcopy_swap32(&e->ce_data.leaf[2],
228 228 (uint32_t *)inq->inq_vid,
229 229 min(sizeof (inq->inq_vid) / 4, len));
230 230 } else if (eref->ce_kv == 0x17) {
231 231 bcopy_swap32(&e->ce_data.leaf[2],
232 232 (uint32_t *)inq->inq_pid,
233 233 min(sizeof (inq->inq_pid) / 4, len));
234 234 } else if ((eref->ce_kv == IEEE1212_MODULE_HW_VERSION) ||
235 235 (eref == evid)) {
236 236 bcopy_swap32(&e->ce_data.leaf[2],
237 237 (uint32_t *)inq->inq_revision,
238 238 min(sizeof (inq->inq_revision) / 4, len));
239 239 }
240 240 }
241 241 }
242 242
243 243 int
244 244 scsa1394_sbp2_threads_init(scsa1394_state_t *sp)
245 245 {
246 246 scsa1394_lun_t *lp;
247 247 scsa1394_thread_t *thr;
248 248 int i;
249 249
250 250 for (i = 0; i < sp->s_nluns; i++) {
251 251 lp = &sp->s_lun[i];
252 252 thr = &lp->l_worker_thread;
253 253
254 254 thr->thr_func = scsa1394_sbp2_worker_thread;
255 255 thr->thr_arg = thr;
256 256 thr->thr_state = SCSA1394_THR_INIT;
257 257 cv_init(&thr->thr_cv, NULL, CV_DRIVER, NULL);
258 258 thr->thr_lun = lp;
259 259 thr->thr_req = 0;
260 260
261 261 mutex_enter(&lp->l_mutex);
262 262 if (scsa1394_thr_dispatch(thr) != DDI_SUCCESS) {
263 263 mutex_exit(&lp->l_mutex);
264 264 scsa1394_sbp2_threads_fini(sp);
265 265 return (DDI_FAILURE);
266 266 }
267 267 mutex_exit(&lp->l_mutex);
268 268 }
269 269
270 270 return (DDI_SUCCESS);
271 271 }
272 272
273 273 void
274 274 scsa1394_sbp2_threads_fini(scsa1394_state_t *sp)
275 275 {
276 276 scsa1394_lun_t *lp;
277 277 scsa1394_thread_t *thr;
278 278 int i;
279 279
280 280 for (i = 0; i < sp->s_nluns; i++) {
281 281 lp = &sp->s_lun[i];
282 282 thr = &lp->l_worker_thread;
283 283
284 284 /* if thread wasn't initialized, thr_lun will be NULL */
285 285 if (thr->thr_lun == lp) {
286 286 mutex_enter(&lp->l_mutex);
287 287 scsa1394_thr_cancel(thr);
288 288 mutex_exit(&lp->l_mutex);
289 289 ASSERT(thr->thr_state != SCSA1394_THR_RUN);
290 290 cv_destroy(&thr->thr_cv);
291 291 }
292 292 }
293 293 }
294 294
295 295 int
296 296 scsa1394_sbp2_get_lun_type(scsa1394_lun_t *lp)
297 297 {
298 298 return (lp->l_lun->l_type);
299 299 }
300 300
301 301 int
302 302 scsa1394_sbp2_login(scsa1394_state_t *sp, int lun)
303 303 {
304 304 scsa1394_lun_t *lp = &sp->s_lun[lun];
305 305 int berr;
306 306
307 307 if (sbp2_lun_login(lp->l_lun, &lp->l_ses,
308 308 scsa1394_sbp2_status_cb, lp, &berr) != SBP2_SUCCESS) {
309 309 return (DDI_FAILURE);
310 310 }
311 311 ASSERT(lp->l_ses != NULL);
312 312 return (DDI_SUCCESS);
313 313 }
314 314
315 315 void
316 316 scsa1394_sbp2_logout(scsa1394_state_t *sp, int lun, boolean_t phys)
317 317 {
318 318 scsa1394_lun_t *lp = &sp->s_lun[lun];
319 319 int berr;
320 320
321 321 if (scsa1394_sbp2_logged_in(lp)) {
322 322 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, phys);
323 323 }
324 324 }
325 325
326 326 void
327 327 scsa1394_sbp2_req(scsa1394_state_t *sp, int lun, int req)
328 328 {
329 329 scsa1394_lun_t *lp = &sp->s_lun[lun];
330 330
331 331 if (lp != NULL) {
332 332 mutex_enter(&lp->l_mutex);
333 333 scsa1394_thr_wake(&lp->l_worker_thread, req);
334 334 mutex_exit(&lp->l_mutex);
335 335 }
336 336 }
337 337
338 338 void
339 339 scsa1394_sbp2_req_bus_reset(scsa1394_lun_t *lp)
340 340 {
341 341 scsa1394_state_t *sp = lp->l_sp;
342 342 int berr = 0;
343 343
344 344 if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0,
345 345 &sp->s_targetinfo) != DDI_SUCCESS) {
346 346 goto disconnect;
347 347 }
348 348
349 349 if (sp->s_targetinfo.target_nodeID == T1394_INVALID_NODEID) {
350 350 goto disconnect;
351 351 }
352 352
353 353 if (!scsa1394_sbp2_logged_in(lp)) {
354 354 /* reconnect procedure is only for logged in hosts */
355 355 return;
356 356 }
357 357
358 358 /*
359 359 * Try SBP-2 RECONNECT procedure first. Note that we're passing
360 360 * local Node ID, which might have changed during bus reset.
361 361 * sbp2_ses_reconnect() will use it to update the ORBs.
362 362 */
363 363 if (sbp2_ses_reconnect(lp->l_ses, &berr,
364 364 SCSA1394_NODEID(sp)) == SBP2_SUCCESS) {
365 365 mutex_enter(&sp->s_mutex);
366 366 sp->s_dev_state = SCSA1394_DEV_ONLINE;
367 367 mutex_exit(&sp->s_mutex);
368 368
369 369 /* resume task processing */
370 370 scsa1394_sbp2_nudge(lp);
371 371
372 372 return;
373 373 }
374 374
375 375 if (berr == CMD1394_EDEVICE_REMOVED) {
376 376 goto disconnect;
377 377 }
378 378
379 379 /* reconnect failed, try to logout and login again */
380 380 scsa1394_sbp2_flush_cmds(lp, CMD_TRAN_ERR, 0, STAT_BUS_RESET);
381 381 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
382 382
383 383 if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) {
384 384 goto disconnect;
385 385 }
386 386
387 387 mutex_enter(&sp->s_mutex);
388 388 sp->s_dev_state = SCSA1394_DEV_ONLINE;
389 389 mutex_exit(&sp->s_mutex);
390 390
391 391 return;
392 392
393 393 disconnect:
394 394 mutex_enter(&sp->s_mutex);
395 395 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED;
396 396 mutex_exit(&sp->s_mutex);
397 397 if (scsa1394_sbp2_logged_in(lp)) {
398 398 scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET);
399 399 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
400 400 }
401 401 }
402 402
403 403 /*ARGSUSED*/
404 404 void
405 405 scsa1394_sbp2_req_reconnect(scsa1394_lun_t *lp)
406 406 {
407 407 scsa1394_state_t *sp = lp->l_sp;
408 408
409 409 if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0,
410 410 &sp->s_targetinfo) != DDI_SUCCESS) {
411 411 return;
412 412 }
413 413
414 414 mutex_enter(&sp->s_mutex);
415 415 sp->s_dev_state = SCSA1394_DEV_ONLINE;
416 416 mutex_exit(&sp->s_mutex);
417 417
418 418 if (sbp2_tgt_reconnect(sp->s_tgt) != SBP2_SUCCESS) {
419 419 goto disconnect;
420 420 }
421 421
422 422 if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) {
423 423 goto disconnect;
424 424 }
425 425
426 426 cmn_err(CE_WARN, "scsa1394(%d): "
427 427 "Reinserted device is accessible again.\n", sp->s_instance);
428 428
429 429 return;
430 430
431 431 disconnect:
432 432 mutex_enter(&sp->s_mutex);
433 433 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED;
434 434 mutex_exit(&sp->s_mutex);
435 435 }
436 436
437 437 void
438 438 scsa1394_sbp2_disconnect(scsa1394_state_t *sp)
439 439 {
440 440 scsa1394_lun_t *lp = &sp->s_lun[0];
441 441 int berr;
442 442
443 443 scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET);
444 444 if (scsa1394_sbp2_logged_in(lp)) {
445 445 (void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
446 446 }
447 447 sbp2_tgt_disconnect(sp->s_tgt);
448 448 }
449 449
450 450 /*
451 451 * convert segment array into DMA-mapped SBP-2 page table
452 452 */
453 453 void
454 454 scsa1394_sbp2_seg2pt(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
455 455 {
456 456 scsa1394_state_t *sp = lp->l_sp;
457 457
458 458 ASSERT(cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID);
459 459
460 460 if (sp->s_symbios) {
461 461 scsa1394_sbp2_seg2pt_symbios(lp, cmd);
462 462 } else {
463 463 scsa1394_sbp2_seg2pt_default(lp, cmd);
464 464 }
465 465 }
466 466
467 467 /*ARGSUSED*/
468 468 static void
469 469 scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
470 470 {
471 471 sbp2_pt_unrestricted_t *pt;
472 472 scsa1394_cmd_seg_t *seg;
473 473 int i;
474 474
475 475 pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr;
476 476 seg = &cmd->sc_buf_seg[0];
477 477 for (i = 0; i < cmd->sc_buf_nsegs; i++) {
478 478 pt->pt_seg_len = SBP2_SWAP16(seg->ss_len);
479 479 pt->pt_seg_base_hi = SBP2_SWAP16(seg->ss_baddr >> 32);
480 480 pt->pt_seg_base_lo = SBP2_SWAP32(seg->ss_baddr & 0xFFFFFFFF);
481 481
482 482 pt++;
483 483 seg++;
484 484 }
485 485 (void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
486 486
487 487 cmd->sc_pt_cmd_size = cmd->sc_buf_nsegs;
488 488 }
489 489
490 490 /*
491 491 * fill page table for Symbios workaround
492 492 */
493 493 /*ARGSUSED*/
494 494 static void
495 495 scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
496 496 {
497 497 sbp2_pt_unrestricted_t *pt;
498 498 scsa1394_cmd_seg_t *seg;
499 499 int nsegs;
500 500 size_t resid, skiplen, dataoff, segoff, seglen;
501 501 uint64_t baddr;
502 502
503 503 /* data offset within command */
504 504 if (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP) {
505 505 dataoff = (cmd->sc_total_blks - cmd->sc_resid_blks) *
506 506 cmd->sc_blk_size;
507 507 } else {
508 508 dataoff = 0;
509 509 }
510 510
511 511 /* skip dataoff bytes */
512 512 seg = &cmd->sc_buf_seg[0];
513 513 skiplen = 0;
514 514 while (skiplen + seg->ss_len <= dataoff) {
515 515 skiplen += seg->ss_len;
516 516 seg++;
517 517 }
518 518 segoff = dataoff - skiplen; /* offset within segment */
519 519
520 520 pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr;
521 521 resid = cmd->sc_xfer_bytes;
522 522 nsegs = 0;
523 523 while (resid > 0) {
524 524 ASSERT(seg->ss_len <= scsa1394_symbios_page_size);
525 525
526 526 seglen = min(seg->ss_len, resid) - segoff;
527 527 baddr = seg->ss_baddr + segoff;
528 528
529 529 pt->pt_seg_len = SBP2_SWAP16(seglen);
530 530 pt->pt_seg_base_hi = SBP2_SWAP16(baddr >> 32);
531 531 pt->pt_seg_base_lo = SBP2_SWAP32(baddr & 0xFFFFFFFF);
532 532
533 533 segoff = 0;
534 534 resid -= seglen;
535 535 nsegs++;
536 536 pt++;
537 537 seg++;
538 538 }
539 539 (void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
540 540
541 541 cmd->sc_pt_cmd_size = nsegs;
542 542 }
543 543
544 544 /*
545 545 * convert command into DMA-mapped SBP-2 ORB
546 546 */
547 547 void
548 548 scsa1394_sbp2_cmd2orb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
549 549 {
↓ open down ↓ |
549 lines elided |
↑ open up ↑ |
550 550 scsa1394_state_t *sp = lp->l_sp;
551 551 scsa1394_cmd_orb_t *orb = sbp2_task_orb_kaddr(&cmd->sc_task);
552 552
553 553 mutex_enter(&lp->l_mutex);
554 554
555 555 lp->l_stat.stat_cmd_cnt++;
556 556
557 557 bzero(orb->co_cdb, sizeof (orb->co_cdb));
558 558
559 559 /* CDB */
560 - bcopy(cmd->sc_cdb, orb->co_cdb, cmd->sc_cdb_actual_len);
560 + bcopy(cmd->sc_pkt->pkt_cdbp, orb->co_cdb, cmd->sc_orig_cdblen);
561 561
562 562 /*
563 563 * ORB parameters
564 564 *
565 565 * use max speed and max payload for this speed.
566 566 * max async data transfer for a given speed is 512<<speed
567 567 * SBP-2 defines (see 5.1.2) max data transfer as 2^(max_payload+2),
568 568 * hence max_payload = 7 + speed
569 569 */
570 570 orb->co_params = SBP2_ORB_NOTIFY | SBP2_ORB_RQ_FMT_SBP2 |
571 571 (sp->s_targetinfo.current_max_speed << SBP2_ORB_CMD_SPD_SHIFT) |
572 572 ((7 + sp->s_targetinfo.current_max_speed -
573 573 scsa1394_sbp2_max_payload_sub) << SBP2_ORB_CMD_MAX_PAYLOAD_SHIFT);
574 574
575 575 /* direction: initiator's read is target's write (and vice versa) */
576 576 if (cmd->sc_flags & SCSA1394_CMD_READ) {
577 577 orb->co_params |= SBP2_ORB_CMD_DIR;
578 578 }
579 579
580 580 /*
581 581 * data_size and data_descriptor
582 582 */
583 583 if (cmd->sc_buf_nsegs == 0) {
584 584 /* no data */
585 585 orb->co_data_size = 0;
586 586 SCSA1394_ADDR_SET(sp, orb->co_data_descr, 0);
587 587 } else if (cmd->sc_buf_nsegs == 1) {
588 588 /* contiguous buffer - use direct addressing */
589 589 ASSERT(cmd->sc_buf_seg[0].ss_len != 0);
590 590 orb->co_data_size = SBP2_SWAP16(cmd->sc_buf_seg[0].ss_len);
591 591 SCSA1394_ADDR_SET(sp, orb->co_data_descr,
592 592 cmd->sc_buf_seg[0].ss_baddr);
593 593 } else {
594 594 /* non-contiguous s/g list - page table */
595 595 ASSERT(cmd->sc_pt_cmd_size > 0);
596 596 orb->co_params |= SBP2_ORB_CMD_PT;
597 597 orb->co_data_size = SBP2_SWAP16(cmd->sc_pt_cmd_size);
598 598 SCSA1394_ADDR_SET(sp, orb->co_data_descr, cmd->sc_pt_baddr);
599 599 }
600 600
601 601 SBP2_SWAP16_1(orb->co_params);
602 602
603 603 SBP2_ORBP_SET(orb->co_next_orb, SBP2_ORBP_NULL);
604 604
605 605 mutex_exit(&lp->l_mutex);
606 606
607 607 sbp2_task_orb_sync(lp->l_lun, &cmd->sc_task, DDI_DMA_SYNC_FORDEV);
608 608 }
609 609
610 610
611 611 /*ARGSUSED*/
612 612 int
613 613 scsa1394_sbp2_start(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
614 614 {
615 615 sbp2_task_t *task = CMD2TASK(cmd);
616 616 int ret;
617 617
618 618 ASSERT(lp->l_ses != NULL);
619 619
620 620 task->ts_timeout = cmd->sc_timeout;
621 621 task->ts_error = SBP2_TASK_ERR_NONE;
622 622 task->ts_bus_error = 0;
623 623 task->ts_state = SBP2_TASK_INIT;
624 624
625 625 ret = sbp2_ses_submit_task(lp->l_ses, task);
626 626
627 627 if ((ret == SBP2_SUCCESS) || (ret == SBP2_ECONTEXT)) {
628 628 return (TRAN_ACCEPT);
629 629 } if (task->ts_error == SBP2_TASK_ERR_BUS) {
630 630 if (task->ts_bus_error == CMD1394_EDEVICE_BUSY) {
631 631 return (TRAN_BUSY);
632 632 } else {
633 633 return (TRAN_FATAL_ERROR);
634 634 }
635 635 } else {
636 636 return (TRAN_FATAL_ERROR);
637 637 }
638 638 }
639 639
640 640 /*
641 641 * This function is called by SBP-2 layer when task status is received,
642 642 * typically from interrupt handler. Just wake the thread to do the actual work.
643 643 */
644 644 /*ARGSUSED*/
645 645 static void
646 646 scsa1394_sbp2_status_cb(void *arg, sbp2_task_t *task)
647 647 {
648 648 scsa1394_lun_t *lp = (scsa1394_lun_t *)arg;
649 649
650 650 mutex_enter(&lp->l_mutex);
651 651 scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_TASK_STATUS);
652 652 mutex_exit(&lp->l_mutex);
653 653 }
654 654
655 655 void
656 656 scsa1394_sbp2_nudge(scsa1394_lun_t *lp)
657 657 {
658 658 mutex_enter(&lp->l_mutex);
659 659 scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_NUDGE);
660 660 mutex_exit(&lp->l_mutex);
661 661 }
662 662
663 663 /*
664 664 * worker thread
665 665 */
666 666 static void
667 667 scsa1394_sbp2_worker_thread(void *arg)
668 668 {
669 669 scsa1394_thread_t *thr = (scsa1394_thread_t *)arg;
670 670 scsa1394_lun_t *lp = thr->thr_lun;
671 671
672 672 mutex_enter(&lp->l_mutex);
673 673 for (;;) {
674 674 while (thr->thr_req == 0) {
675 675 cv_wait(&thr->thr_cv, &lp->l_mutex);
676 676 }
677 677 if (thr->thr_req & SCSA1394_THREQ_EXIT) {
678 678 break;
679 679 }
680 680 if (thr->thr_req & SCSA1394_THREQ_BUS_RESET) {
681 681 thr->thr_req &= ~SCSA1394_THREQ_BUS_RESET;
682 682 mutex_exit(&lp->l_mutex);
683 683 scsa1394_sbp2_req_bus_reset(lp);
684 684 mutex_enter(&lp->l_mutex);
685 685 continue;
686 686 }
687 687 if (thr->thr_req & SCSA1394_THREQ_RECONNECT) {
688 688 thr->thr_req &= ~SCSA1394_THREQ_RECONNECT;
689 689 mutex_exit(&lp->l_mutex);
690 690 scsa1394_sbp2_req_reconnect(lp);
691 691 mutex_enter(&lp->l_mutex);
692 692 continue;
693 693 }
694 694 if (thr->thr_req & SCSA1394_THREQ_TASK_STATUS) {
695 695 thr->thr_req &= ~SCSA1394_THREQ_TASK_STATUS;
696 696 mutex_exit(&lp->l_mutex);
697 697 scsa1394_sbp2_req_status(lp);
698 698 mutex_enter(&lp->l_mutex);
699 699 continue;
700 700 }
701 701 if (thr->thr_req & SCSA1394_THREQ_NUDGE) {
702 702 thr->thr_req &= ~SCSA1394_THREQ_NUDGE;
703 703 mutex_exit(&lp->l_mutex);
704 704 if (scsa1394_sbp2_logged_in(lp)) {
705 705 sbp2_ses_nudge(lp->l_ses);
706 706 }
707 707 mutex_enter(&lp->l_mutex);
708 708 continue;
709 709 }
710 710 }
711 711 thr->thr_state = SCSA1394_THR_EXIT;
712 712 cv_signal(&thr->thr_cv);
713 713 mutex_exit(&lp->l_mutex);
714 714 }
715 715
716 716 /*
717 717 * task status handler
718 718 */
719 719 static void
720 720 scsa1394_sbp2_req_status(scsa1394_lun_t *lp)
721 721 {
722 722 sbp2_ses_t *sp = lp->l_ses;
723 723 sbp2_task_t *task;
724 724
725 725 if (sp == NULL) {
726 726 return;
727 727 }
728 728
729 729 /*
730 730 * Process all tasks that received status.
731 731 * This algorithm preserves callback order.
732 732 */
733 733 while ((task = sbp2_ses_remove_first_task_state(sp, SBP2_TASK_COMP)) !=
734 734 NULL) {
735 735 sbp2_ses_nudge(sp);
736 736
737 737 ASSERT(task->ts_state == SBP2_TASK_COMP);
738 738 task->ts_state = SBP2_TASK_PROC;
739 739 scsa1394_sbp2_status_proc(lp, TASK2CMD(task),
740 740 (scsa1394_status_t *)&task->ts_status);
741 741 }
742 742 sbp2_ses_nudge(sp); /* submit next task */
743 743 }
744 744
745 745 static void
746 746 scsa1394_sbp2_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd,
747 747 scsa1394_status_t *st)
748 748 {
749 749 sbp2_task_t *task = CMD2TASK(cmd);
750 750 struct scsi_pkt *pkt = CMD2PKT(cmd);
751 751 uint64_t *p;
752 752
753 753 if (cmd->sc_flags & SCSA1394_CMD_READ) {
754 754 (void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0,
755 755 DDI_DMA_SYNC_FORKERNEL);
756 756 }
757 757
758 758 if (task->ts_error != SBP2_TASK_ERR_NONE) {
759 759 pkt->pkt_state |= STATE_GOT_BUS;
760 760 switch (task->ts_error) {
761 761 case SBP2_TASK_ERR_ABORT:
762 762 pkt->pkt_state |= STATE_GOT_TARGET;
763 763 pkt->pkt_reason = CMD_ABORTED;
764 764 break;
765 765 case SBP2_TASK_ERR_LUN_RESET:
766 766 pkt->pkt_state |= STATE_GOT_TARGET;
767 767 pkt->pkt_reason = CMD_RESET;
768 768 pkt->pkt_statistics |= STAT_DEV_RESET;
769 769 break;
770 770 case SBP2_TASK_ERR_TGT_RESET:
771 771 pkt->pkt_state |= STATE_GOT_TARGET;
772 772 pkt->pkt_reason = CMD_RESET;
773 773 pkt->pkt_statistics |= STAT_DEV_RESET;
774 774 break;
775 775 case SBP2_TASK_ERR_TIMEOUT:
776 776 (void) scsa1394_sbp2_reset(lp, RESET_TARGET, cmd);
777 777 return;
778 778 case SBP2_TASK_ERR_DEAD:
779 779 case SBP2_TASK_ERR_BUS:
780 780 default:
781 781 pkt->pkt_reason = CMD_TRAN_ERR;
782 782 break;
783 783 }
784 784 } else if ((st->st_param & SBP2_ST_RESP) == SBP2_ST_RESP_COMPLETE) {
785 785 /*
786 786 * SBP-2 status block has been received, now look at sbp_status.
787 787 *
788 788 * Note: ANSI NCITS 325-1998 B.2 requires that when status is
789 789 * GOOD, length must be one, but some devices do not comply
790 790 */
791 791 if (st->st_sbp_status == SBP2_ST_SBP_DUMMY_ORB) {
792 792 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
793 793 pkt->pkt_reason = CMD_ABORTED;
794 794 pkt->pkt_statistics |= STAT_DEV_RESET;
795 795 } else if ((st->st_status & SCSA1394_ST_STATUS) ==
796 796 STATUS_GOOD) {
797 797 /* request complete */
798 798 *(pkt->pkt_scbp) = STATUS_GOOD;
799 799 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
800 800 STATE_SENT_CMD | STATE_XFERRED_DATA |
801 801 STATE_GOT_STATUS);
802 802 pkt->pkt_reason = CMD_CMPLT;
803 803 } else if (scsa1394_sbp2_conv_status(cmd, st) == DDI_SUCCESS) {
804 804 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
805 805 STATE_SENT_CMD | STATE_XFERRED_DATA |
806 806 STATE_GOT_STATUS | STATE_ARQ_DONE);
807 807 pkt->pkt_reason = CMD_TRAN_ERR;
808 808 } else {
809 809 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
810 810 STATE_SENT_CMD | STATE_XFERRED_DATA |
811 811 STATE_GOT_STATUS);
812 812 pkt->pkt_reason = CMD_TRAN_ERR;
813 813 lp->l_stat.stat_err_status_conv++;
814 814 }
815 815 } else {
816 816 /* transport or serial bus failure */
817 817 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
↓ open down ↓ |
247 lines elided |
↑ open up ↑ |
818 818 pkt->pkt_reason = CMD_TRAN_ERR;
819 819 lp->l_stat.stat_err_status_resp++;
820 820 }
821 821
822 822 if (pkt->pkt_reason == CMD_TRAN_ERR) {
823 823 lp->l_stat.stat_err_status_tran_err++;
824 824
825 825 /* save the command */
826 826 p = &lp->l_stat.stat_cmd_last_fail[
827 827 lp->l_stat.stat_cmd_last_fail_idx][0];
828 - bcopy(&pkt->pkt_cdbp[0], p, min(cmd->sc_cdb_len, 16));
828 + bcopy(&pkt->pkt_cdbp[0], p, min(cmd->sc_pkt->pkt_cdblen, 16));
829 829 *(clock_t *)&p[2] = ddi_get_lbolt();
830 830 lp->l_stat.stat_cmd_last_fail_idx =
831 831 (lp->l_stat.stat_cmd_last_fail_idx + 1) %
832 832 SCSA1394_STAT_NCMD_LAST;
833 833 }
834 834
835 835 /* generic HBA status processing */
836 836 scsa1394_cmd_status_proc(lp, cmd);
837 837 }
838 838
839 839
840 840 /*
841 841 * Convert SBP-2 status block into SCSA status.
842 842 *
843 843 * Note: (ref: B.2) "SBP-2 permits the return of a status block between two
844 844 * and quadlets in length. When a truncated status block is stored, the
845 845 * omitted quadlets shall be interpreted as if zero values were stored."
846 846 * We expect the sbp2 layer to do the zeroing for us.
847 847 */
848 848 static int
849 849 scsa1394_sbp2_conv_status(scsa1394_cmd_t *cmd, scsa1394_status_t *st)
850 850 {
851 851 struct scsi_pkt *pkt = CMD2PKT(cmd);
852 852 uint8_t status = st->st_status;
853 853 uint8_t bits = st->st_sense_bits;
854 854 struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp;
855 855 struct scsi_extended_sense *esp = &arqp->sts_sensedata;
856 856
857 857 *(pkt->pkt_scbp) = (status & SCSA1394_ST_STATUS);
858 858 *(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD;
859 859 arqp->sts_rqpkt_reason = CMD_CMPLT;
860 860 arqp->sts_rqpkt_resid = 0;
861 861 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
862 862 arqp->sts_rqpkt_statistics = 0;
863 863
864 864 esp->es_valid = (bits & SCSA1394_ST_VALID) >> SCSA1394_ST_VALID_SHIFT;
865 865 esp->es_class = CLASS_EXTENDED_SENSE;
866 866 esp->es_code = (status & SCSA1394_ST_SFMT) >> SCSA1394_ST_SFMT_SHIFT;
867 867
868 868 esp->es_segnum = 0;
869 869
870 870 esp->es_filmk = (bits & SCSA1394_ST_MARK) >> SCSA1394_ST_MARK_SHIFT;
871 871 esp->es_eom = (bits & SCSA1394_ST_EOM) >> SCSA1394_ST_EOM_SHIFT;
872 872 esp->es_ili = (bits & SCSA1394_ST_ILI) >> SCSA1394_ST_ILI_SHIFT;
873 873 esp->es_key = (bits & SCSA1394_ST_SENSE_KEY);
874 874
875 875 esp->es_info_1 = st->st_info[0];
876 876 esp->es_info_2 = st->st_info[1];
877 877 esp->es_info_3 = st->st_info[2];
878 878 esp->es_info_4 = st->st_info[3];
879 879 esp->es_add_len = 4;
880 880
881 881 esp->es_cmd_info[0] = st->st_cdb[0];
882 882 esp->es_cmd_info[1] = st->st_cdb[1];
883 883 esp->es_cmd_info[2] = st->st_cdb[2];
884 884 esp->es_cmd_info[3] = st->st_cdb[3];
885 885 esp->es_add_code = st->st_sense_code;
886 886 esp->es_qual_code = st->st_sense_qual;
887 887 esp->es_fru_code = st->st_fru;
888 888 esp->es_skey_specific[0] = st->st_sks[0];
889 889 esp->es_skey_specific[1] = st->st_sks[1];
890 890 esp->es_skey_specific[2] = st->st_sks[2];
891 891
892 892 esp->es_add_info[0] = esp->es_add_info[1] = 0;
893 893
894 894 return (DDI_SUCCESS);
895 895 }
896 896
897 897 /*
898 898 * Sends appropriate reset command to the target. LUN reset is optional, so it
899 899 * can fail, in which case the SCSA target driver will use RESET_TARGET/ALL.
900 900 * Target reset support is mandatory in SBP-2, if it fails, it means something's
901 901 * terribly wrong with the device - blow away outstanding tasks in that case.
902 902 */
903 903 int
904 904 scsa1394_sbp2_reset(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd)
905 905 {
906 906 scsa1394_state_t *sp = lp->l_sp;
907 907 sbp2_task_t *task;
908 908 int berr;
909 909 int ret = DDI_FAILURE;
910 910
911 911 if (scsa1394_dev_is_online(sp)) {
912 912 switch (level) {
913 913 case RESET_LUN:
914 914 ret = sbp2_lun_reset(lp->l_lun, &berr);
915 915 if (ret != SBP2_SUCCESS) {
916 916 return (ret);
917 917 }
918 918 break;
919 919 case RESET_TARGET:
920 920 case RESET_ALL:
921 921 ret = sbp2_tgt_reset(sp->s_tgt, &berr);
922 922 break;
923 923 }
924 924 }
925 925
926 926 if (cmd != NULL) {
927 927 scsa1394_sbp2_reset_proc(lp, level, cmd);
928 928 }
929 929 if (scsa1394_sbp2_logged_in(lp)) {
930 930 while ((task = sbp2_ses_cancel_first_task(lp->l_ses)) != NULL) {
931 931 ASSERT(task->ts_state < SBP2_TASK_PROC);
932 932 scsa1394_sbp2_reset_proc(lp, level, TASK2CMD(task));
933 933 }
934 934 }
935 935
936 936 return (ret);
937 937 }
938 938
939 939 static void
940 940 scsa1394_sbp2_reset_proc(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd)
941 941 {
942 942 sbp2_task_t *task = CMD2TASK(cmd);
943 943 struct scsi_pkt *pkt = CMD2PKT(cmd);
944 944 int ts_error;
945 945
946 946 pkt->pkt_reason = CMD_RESET;
947 947 if (level == RESET_LUN) {
948 948 if (task->ts_state == SBP2_TASK_PEND) {
949 949 pkt->pkt_statistics |= STAT_DEV_RESET;
950 950 } else {
951 951 pkt->pkt_statistics |= STAT_ABORTED;
952 952 }
953 953 ts_error = SBP2_TASK_ERR_LUN_RESET;
954 954 } else {
955 955 pkt->pkt_statistics |= STAT_BUS_RESET;
956 956 ts_error = SBP2_TASK_ERR_TGT_RESET;
957 957 }
958 958 task->ts_error = ts_error;
959 959 task->ts_state = SBP2_TASK_PROC;
960 960 scsa1394_cmd_status_proc(lp, cmd);
961 961 }
962 962
963 963 /*
964 964 * Cancel commands immediately.
965 965 *
966 966 * Caller's responsibility to set device state such that no new tasks are added.
967 967 */
968 968 void
969 969 scsa1394_sbp2_flush_cmds(scsa1394_lun_t *lp, int reason, int state,
970 970 int statistics)
971 971 {
972 972 scsa1394_cmd_t *cmd;
973 973 struct scsi_pkt *pkt;
974 974 sbp2_ses_t *sp = lp->l_ses;
975 975 sbp2_task_t *task;
976 976
977 977 if (sp == NULL) {
978 978 return;
979 979 }
980 980
981 981 while ((task = sbp2_ses_cancel_first_task(sp)) != NULL) {
982 982 ASSERT(task->ts_state < SBP2_TASK_PROC);
983 983 cmd = TASK2CMD(task);
984 984 pkt = CMD2PKT(cmd);
985 985
986 986 pkt->pkt_reason = reason;
987 987 pkt->pkt_state |= state;
988 988 pkt->pkt_statistics |= statistics;
989 989 task->ts_state = SBP2_TASK_PROC;
990 990 scsa1394_cmd_status_proc(lp, cmd);
991 991 }
992 992
993 993 scsa1394_thr_clear_req(&lp->l_worker_thread,
994 994 SCSA1394_THREQ_TASK_STATUS | SCSA1394_THREQ_NUDGE);
995 995 }
996 996
997 997 static boolean_t
998 998 scsa1394_sbp2_logged_in(scsa1394_lun_t *lp)
999 999 {
1000 1000 return (lp->l_ses != NULL);
1001 1001 }
↓ open down ↓ |
163 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX