Deleted Added
full compact
dpt_scsi.c (232185) dpt_scsi.c (241593)
1/*-
2 * Copyright (c) 1997 by Simon Shapiro
3 * All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997 by Simon Shapiro
3 * All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_scsi.c 232185 2012-02-26 16:05:20Z kevlo $");
31__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_scsi.c 241593 2012-10-15 16:29:08Z jhb $");
32
33/*
34 * dpt_scsi.c: SCSI dependant code for the DPT driver
35 *
36 * credits: Assisted by Mike Neuffer in the early low level DPT code
37 * Thanx to Mark Salyzyn of DPT for his assistance.
38 * Special thanx to Justin Gibbs for invaluable help in
39 * making this driver look and work like a FreeBSD component.

--- 8 unchanged lines hidden (view full) ---

48
49#define _DPT_C_
50
51#include "opt_dpt.h"
52#include "opt_eisa.h"
53
54#include <sys/param.h>
55#include <sys/systm.h>
32
33/*
34 * dpt_scsi.c: SCSI dependant code for the DPT driver
35 *
36 * credits: Assisted by Mike Neuffer in the early low level DPT code
37 * Thanx to Mark Salyzyn of DPT for his assistance.
38 * Special thanx to Justin Gibbs for invaluable help in
39 * making this driver look and work like a FreeBSD component.

--- 8 unchanged lines hidden (view full) ---

48
49#define _DPT_C_
50
51#include "opt_dpt.h"
52#include "opt_eisa.h"
53
54#include <sys/param.h>
55#include <sys/systm.h>
56#include <sys/conf.h>
56#include <sys/eventhandler.h>
57#include <sys/malloc.h>
58#include <sys/kernel.h>
59
60#include <sys/bus.h>
61
62#include <machine/bus.h>
63

--- 10 unchanged lines hidden (view full) ---

74#include <cam/scsi/scsi_message.h>
75
76#include <vm/vm.h>
77#include <vm/pmap.h>
78
79#include <dev/dpt/dpt.h>
80
81/* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */
57#include <sys/eventhandler.h>
58#include <sys/malloc.h>
59#include <sys/kernel.h>
60
61#include <sys/bus.h>
62
63#include <machine/bus.h>
64

--- 10 unchanged lines hidden (view full) ---

75#include <cam/scsi/scsi_message.h>
76
77#include <vm/vm.h>
78#include <vm/pmap.h>
79
80#include <dev/dpt/dpt.h>
81
82/* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */
82int dpt_controllers_present;
83devclass_t dpt_devclass;
84
85#define microtime_now dpt_time_now()
86
87#define dpt_inl(dpt, port) \
83devclass_t dpt_devclass;
84
85#define microtime_now dpt_time_now()
86
87#define dpt_inl(dpt, port) \
88 bus_space_read_4((dpt)->tag, (dpt)->bsh, port)
88 bus_read_4((dpt)->io_res, (dpt)->io_offset + port)
89#define dpt_inb(dpt, port) \
89#define dpt_inb(dpt, port) \
90 bus_space_read_1((dpt)->tag, (dpt)->bsh, port)
90 bus_read_1((dpt)->io_res, (dpt)->io_offset + port)
91#define dpt_outl(dpt, port, value) \
91#define dpt_outl(dpt, port, value) \
92 bus_space_write_4((dpt)->tag, (dpt)->bsh, port, value)
92 bus_write_4((dpt)->io_res, (dpt)->io_offset + port, value)
93#define dpt_outb(dpt, port, value) \
93#define dpt_outb(dpt, port, value) \
94 bus_space_write_1((dpt)->tag, (dpt)->bsh, port, value)
94 bus_write_1((dpt)->io_res, (dpt)->io_offset + port, value)
95
96/*
97 * These will have to be setup by parameters passed at boot/load time. For
98 * perfromance reasons, we make them constants for the time being.
99 */
100#define dpt_min_segs DPT_MAX_SEGS
101#define dpt_max_segs DPT_MAX_SEGS
102

--- 34 unchanged lines hidden (view full) ---

137static int dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb,
138 u_int32_t dccb_busaddr, u_int size,
139 u_int page, u_int target, int extent);
140static void dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb,
141 u_int32_t dccb_busaddr,
142 u_int8_t *buff);
143
144static void dpt_poll(struct cam_sim *sim);
95
96/*
97 * These will have to be setup by parameters passed at boot/load time. For
98 * perfromance reasons, we make them constants for the time being.
99 */
100#define dpt_min_segs DPT_MAX_SEGS
101#define dpt_max_segs DPT_MAX_SEGS
102

--- 34 unchanged lines hidden (view full) ---

137static int dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb,
138 u_int32_t dccb_busaddr, u_int size,
139 u_int page, u_int target, int extent);
140static void dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb,
141 u_int32_t dccb_busaddr,
142 u_int8_t *buff);
143
144static void dpt_poll(struct cam_sim *sim);
145static void dpt_intr_locked(dpt_softc_t *dpt);
145
146static void dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs,
147 int nseg, int error);
148
149static void dpt_action(struct cam_sim *sim, union ccb *ccb);
150
151static int dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd,
152 u_int32_t cmd_busaddr,

--- 64 unchanged lines hidden (view full) ---

217 }
218 return (-1);
219}
220
221static __inline struct dpt_ccb*
222dptgetccb(struct dpt_softc *dpt)
223{
224 struct dpt_ccb* dccb;
146
147static void dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs,
148 int nseg, int error);
149
150static void dpt_action(struct cam_sim *sim, union ccb *ccb);
151
152static int dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd,
153 u_int32_t cmd_busaddr,

--- 64 unchanged lines hidden (view full) ---

218 }
219 return (-1);
220}
221
222static __inline struct dpt_ccb*
223dptgetccb(struct dpt_softc *dpt)
224{
225 struct dpt_ccb* dccb;
225 int s;
226
226
227 s = splcam();
227 if (!dumping)
228 mtx_assert(&dpt->lock, MA_OWNED);
228 if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) {
229 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
230 dpt->free_dccbs--;
231 } else if (dpt->total_dccbs < dpt->max_dccbs) {
232 dptallocccbs(dpt);
233 dccb = SLIST_FIRST(&dpt->free_dccb_list);
234 if (dccb == NULL)
229 if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) {
230 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
231 dpt->free_dccbs--;
232 } else if (dpt->total_dccbs < dpt->max_dccbs) {
233 dptallocccbs(dpt);
234 dccb = SLIST_FIRST(&dpt->free_dccb_list);
235 if (dccb == NULL)
235 printf("dpt%d: Can't malloc DCCB\n", dpt->unit);
236 device_printf(dpt->dev, "Can't malloc DCCB\n");
236 else {
237 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
238 dpt->free_dccbs--;
239 }
240 }
237 else {
238 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links);
239 dpt->free_dccbs--;
240 }
241 }
241 splx(s);
242
243 return (dccb);
244}
245
246static __inline void
247dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb)
248{
242
243 return (dccb);
244}
245
246static __inline void
247dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb)
248{
249 int s;
250
249
251 s = splcam();
250 if (!dumping)
251 mtx_assert(&dpt->lock, MA_OWNED);
252 if ((dccb->state & DCCB_ACTIVE) != 0)
253 LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le);
254 if ((dccb->state & DCCB_RELEASE_SIMQ) != 0)
255 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
256 else if (dpt->resource_shortage != 0
257 && (dccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
258 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
259 dpt->resource_shortage = FALSE;
260 }
261 dccb->state = DCCB_FREE;
262 SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links);
263 ++dpt->free_dccbs;
252 if ((dccb->state & DCCB_ACTIVE) != 0)
253 LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le);
254 if ((dccb->state & DCCB_RELEASE_SIMQ) != 0)
255 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
256 else if (dpt->resource_shortage != 0
257 && (dccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
258 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
259 dpt->resource_shortage = FALSE;
260 }
261 dccb->state = DCCB_FREE;
262 SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links);
263 ++dpt->free_dccbs;
264 splx(s);
265}
266
267static __inline bus_addr_t
268dptccbvtop(struct dpt_softc *dpt, struct dpt_ccb *dccb)
269{
270 return (dpt->dpt_ccb_busbase
271 + (u_int32_t)((caddr_t)dccb - (caddr_t)dpt->dpt_dccbs));
272}

--- 54 unchanged lines hidden (view full) ---

327
328 SLIST_INSERT_HEAD(&dpt->sg_maps, sg_map, links);
329
330 return (sg_map);
331}
332
333/*
334 * Allocate another chunk of CCB's. Return count of entries added.
264}
265
266static __inline bus_addr_t
267dptccbvtop(struct dpt_softc *dpt, struct dpt_ccb *dccb)
268{
269 return (dpt->dpt_ccb_busbase
270 + (u_int32_t)((caddr_t)dccb - (caddr_t)dpt->dpt_dccbs));
271}

--- 54 unchanged lines hidden (view full) ---

326
327 SLIST_INSERT_HEAD(&dpt->sg_maps, sg_map, links);
328
329 return (sg_map);
330}
331
332/*
333 * Allocate another chunk of CCB's. Return count of entries added.
335 * Assumed to be called at splcam().
336 */
337static int
338dptallocccbs(dpt_softc_t *dpt)
339{
340 struct dpt_ccb *next_ccb;
341 struct sg_map_node *sg_map;
342 bus_addr_t physaddr;
343 dpt_sg_t *segs;
344 int newcount;
345 int i;
346
334 */
335static int
336dptallocccbs(dpt_softc_t *dpt)
337{
338 struct dpt_ccb *next_ccb;
339 struct sg_map_node *sg_map;
340 bus_addr_t physaddr;
341 dpt_sg_t *segs;
342 int newcount;
343 int i;
344
345 if (!dumping)
346 mtx_assert(&dpt->lock, MA_OWNED);
347 next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs];
348
349 if (next_ccb == dpt->dpt_dccbs) {
350 /*
351 * First time through. Re-use the S/G
352 * space we allocated for initialization
353 * CCBS.
354 */

--- 11 unchanged lines hidden (view full) ---

366 newcount = (PAGE_SIZE / (dpt->sgsize * sizeof(dpt_sg_t)));
367 for (i = 0; dpt->total_dccbs < dpt->max_dccbs && i < newcount; i++) {
368 int error;
369
370 error = bus_dmamap_create(dpt->buffer_dmat, /*flags*/0,
371 &next_ccb->dmamap);
372 if (error != 0)
373 break;
347 next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs];
348
349 if (next_ccb == dpt->dpt_dccbs) {
350 /*
351 * First time through. Re-use the S/G
352 * space we allocated for initialization
353 * CCBS.
354 */

--- 11 unchanged lines hidden (view full) ---

366 newcount = (PAGE_SIZE / (dpt->sgsize * sizeof(dpt_sg_t)));
367 for (i = 0; dpt->total_dccbs < dpt->max_dccbs && i < newcount; i++) {
368 int error;
369
370 error = bus_dmamap_create(dpt->buffer_dmat, /*flags*/0,
371 &next_ccb->dmamap);
372 if (error != 0)
373 break;
374 callout_init_mtx(&next_ccb->timer, &dpt->lock, 0);
374 next_ccb->sg_list = segs;
375 next_ccb->sg_busaddr = htonl(physaddr);
376 next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr);
377 next_ccb->eata_ccb.cp_statDMA = htonl(dpt->sp_physaddr);
378 next_ccb->eata_ccb.cp_reqDMA =
379 htonl(dptccbvtop(dpt, next_ccb)
380 + offsetof(struct dpt_ccb, sense_data));
381 next_ccb->eata_ccb.cp_busaddr = dpt->dpt_ccb_busend;

--- 17 unchanged lines hidden (view full) ---

399 u_int16_t * p;
400 int i;
401
402 /*
403 * Allocate a dpt_conf_t
404 */
405 if (!conf) {
406 conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t),
375 next_ccb->sg_list = segs;
376 next_ccb->sg_busaddr = htonl(physaddr);
377 next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr);
378 next_ccb->eata_ccb.cp_statDMA = htonl(dpt->sp_physaddr);
379 next_ccb->eata_ccb.cp_reqDMA =
380 htonl(dptccbvtop(dpt, next_ccb)
381 + offsetof(struct dpt_ccb, sense_data));
382 next_ccb->eata_ccb.cp_busaddr = dpt->dpt_ccb_busend;

--- 17 unchanged lines hidden (view full) ---

400 u_int16_t * p;
401 int i;
402
403 /*
404 * Allocate a dpt_conf_t
405 */
406 if (!conf) {
407 conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t),
407 M_DEVBUF, M_NOWAIT);
408 M_DEVBUF, M_NOWAIT | M_ZERO);
408 }
409
410 /*
411 * If we didn't get one then we probably won't ever get one.
412 */
413 if (!conf) {
414 printf("dpt: unable to allocate dpt_conf_t\n");
415 return (NULL);
416 }
417
418 /*
409 }
410
411 /*
412 * If we didn't get one then we probably won't ever get one.
413 */
414 if (!conf) {
415 printf("dpt: unable to allocate dpt_conf_t\n");
416 return (NULL);
417 }
418
419 /*
419 * If we have one, clean it up.
420 */
421 bzero(conf, sizeof(dpt_conf_t));
422
423 /*
424 * Reset the controller.
425 */
426 outb((base + HA_WCOMMAND), EATA_CMD_RESET);
427
428 /*
429 * Wait for the controller to become ready.
430 * For some reason there can be -no- delays after calling reset
431 * before we wait on ready status.

--- 61 unchanged lines hidden (view full) ---

493dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
494 u_int size, u_int page, u_int target, int extent)
495{
496 eata_ccb_t *cp;
497
498 u_int8_t status;
499
500 int ndx;
420 * Reset the controller.
421 */
422 outb((base + HA_WCOMMAND), EATA_CMD_RESET);
423
424 /*
425 * Wait for the controller to become ready.
426 * For some reason there can be -no- delays after calling reset
427 * before we wait on ready status.

--- 61 unchanged lines hidden (view full) ---

489dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
490 u_int size, u_int page, u_int target, int extent)
491{
492 eata_ccb_t *cp;
493
494 u_int8_t status;
495
496 int ndx;
501 int ospl;
502 int result;
503
497 int result;
498
499 mtx_assert(&dpt->lock, MA_OWNED);
504 cp = &dccb->eata_ccb;
505 bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp));
506
507 cp->Interpret = 1;
508 cp->DataIn = 1;
509 cp->Auto_Req_Sen = 1;
510 cp->reqlen = sizeof(struct scsi_sense_data);
511

--- 6 unchanged lines hidden (view full) ---

518
519 cp->cp_extent = extent;
520
521 cp->cp_page = page;
522 cp->cp_channel = 0; /* DNC, Interpret mode is set */
523 cp->cp_identify = 1;
524 cp->cp_datalen = htonl(size);
525
500 cp = &dccb->eata_ccb;
501 bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp));
502
503 cp->Interpret = 1;
504 cp->DataIn = 1;
505 cp->Auto_Req_Sen = 1;
506 cp->reqlen = sizeof(struct scsi_sense_data);
507

--- 6 unchanged lines hidden (view full) ---

514
515 cp->cp_extent = extent;
516
517 cp->cp_page = page;
518 cp->cp_channel = 0; /* DNC, Interpret mode is set */
519 cp->cp_identify = 1;
520 cp->cp_datalen = htonl(size);
521
526 ospl = splcam();
527
528 /*
529 * This could be a simple for loop, but we suspected the compiler To
530 * have optimized it a bit too much. Wait for the controller to
531 * become ready
532 */
533 while (((status = dpt_inb(dpt, HA_RSTATUS)) != (HA_SREADY | HA_SSC)
534 && (status != (HA_SREADY | HA_SSC | HA_SERROR))
535 && (status != (HA_SDRDY | HA_SERROR | HA_SDRQ)))
536 || (dpt_wait(dpt, HA_SBUSY, 0))) {
537
538 /*
539 * RAID Drives still Spinning up? (This should only occur if
540 * the DPT controller is in a NON PC (PCI?) platform).
541 */
542 if (dpt_raid_busy(dpt)) {
522 /*
523 * This could be a simple for loop, but we suspected the compiler To
524 * have optimized it a bit too much. Wait for the controller to
525 * become ready
526 */
527 while (((status = dpt_inb(dpt, HA_RSTATUS)) != (HA_SREADY | HA_SSC)
528 && (status != (HA_SREADY | HA_SSC | HA_SERROR))
529 && (status != (HA_SDRDY | HA_SERROR | HA_SDRQ)))
530 || (dpt_wait(dpt, HA_SBUSY, 0))) {
531
532 /*
533 * RAID Drives still Spinning up? (This should only occur if
534 * the DPT controller is in a NON PC (PCI?) platform).
535 */
536 if (dpt_raid_busy(dpt)) {
543 printf("dpt%d WARNING: Get_conf() RSUS failed.\n",
544 dpt->unit);
545 splx(ospl);
537 device_printf(dpt->dev,
538 "WARNING: Get_conf() RSUS failed.\n");
546 return (0);
547 }
548 }
549
550 DptStat_Reset_BUSY(dpt->sp);
551
552 /*
553 * XXXX We might want to do something more clever than aborting at
554 * this point, like resetting (rebooting) the controller and trying
555 * again.
556 */
557 if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
558 EATA_CMD_DMA_SEND_CP,
559 10000, 0, 0, 0)) != 0) {
539 return (0);
540 }
541 }
542
543 DptStat_Reset_BUSY(dpt->sp);
544
545 /*
546 * XXXX We might want to do something more clever than aborting at
547 * this point, like resetting (rebooting) the controller and trying
548 * again.
549 */
550 if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
551 EATA_CMD_DMA_SEND_CP,
552 10000, 0, 0, 0)) != 0) {
560 printf("dpt%d WARNING: Get_conf() failed (%d) to send "
553 device_printf(dpt->dev,
554 "WARNING: Get_conf() failed (%d) to send "
561 "EATA_CMD_DMA_READ_CONFIG\n",
555 "EATA_CMD_DMA_READ_CONFIG\n",
562 dpt->unit, result);
563 splx(ospl);
556 result);
564 return (0);
565 }
566 /* Wait for two seconds for a response. This can be slow */
567 for (ndx = 0;
568 (ndx < 20000)
569 && !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ);
570 ndx++) {
571 DELAY(50);
572 }
573
574 /* Grab the status and clear interrupts */
575 status = dpt_inb(dpt, HA_RSTATUS);
576
557 return (0);
558 }
559 /* Wait for two seconds for a response. This can be slow */
560 for (ndx = 0;
561 (ndx < 20000)
562 && !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ);
563 ndx++) {
564 DELAY(50);
565 }
566
567 /* Grab the status and clear interrupts */
568 status = dpt_inb(dpt, HA_RSTATUS);
569
577 splx(ospl);
578
579 /*
580 * Check the status carefully. Return only if the
581 * command was successful.
582 */
583 if (((status & HA_SERROR) == 0)
584 && (dpt->sp->hba_stat == 0)
585 && (dpt->sp->scsi_stat == 0)
586 && (dpt->sp->residue_len == 0))

--- 9 unchanged lines hidden (view full) ---

596static void
597dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
598 u_int8_t *buff)
599{
600 eata_ccb_t *cp;
601 u_int8_t *param;
602 int bytes;
603 int result;
570 /*
571 * Check the status carefully. Return only if the
572 * command was successful.
573 */
574 if (((status & HA_SERROR) == 0)
575 && (dpt->sp->hba_stat == 0)
576 && (dpt->sp->scsi_stat == 0)
577 && (dpt->sp->residue_len == 0))

--- 9 unchanged lines hidden (view full) ---

587static void
588dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr,
589 u_int8_t *buff)
590{
591 eata_ccb_t *cp;
592 u_int8_t *param;
593 int bytes;
594 int result;
604 int ospl;
605 int ndx;
606 u_int8_t status;
607
595 int ndx;
596 u_int8_t status;
597
598 mtx_assert(&dpt->lock, MA_OWNED);
599
608 /*
609 * Default setting, for best perfromance..
610 * This is what virtually all cards default to..
611 */
612 dpt->cache_type = DPT_CACHE_WRITEBACK;
613 dpt->cache_size = 0;
614
615 cp = &dccb->eata_ccb;

--- 25 unchanged lines hidden (view full) ---

641 */
642 cp->cp_cdb[0] = 0x4d;
643 cp->cp_cdb[1] = 0x0;
644 cp->cp_cdb[2] = 0x40 | 0x33;
645 cp->cp_cdb[7] = 1;
646
647 cp->cp_datalen = htonl(512);
648
600 /*
601 * Default setting, for best perfromance..
602 * This is what virtually all cards default to..
603 */
604 dpt->cache_type = DPT_CACHE_WRITEBACK;
605 dpt->cache_size = 0;
606
607 cp = &dccb->eata_ccb;

--- 25 unchanged lines hidden (view full) ---

633 */
634 cp->cp_cdb[0] = 0x4d;
635 cp->cp_cdb[1] = 0x0;
636 cp->cp_cdb[2] = 0x40 | 0x33;
637 cp->cp_cdb[7] = 1;
638
639 cp->cp_datalen = htonl(512);
640
649 ospl = splcam();
650 result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
651 EATA_CMD_DMA_SEND_CP,
652 10000, 0, 0, 0);
653 if (result != 0) {
641 result = dpt_send_eata_command(dpt, cp, dccb_busaddr,
642 EATA_CMD_DMA_SEND_CP,
643 10000, 0, 0, 0);
644 if (result != 0) {
654 printf("dpt%d WARNING: detect_cache() failed (%d) to send "
655 "EATA_CMD_DMA_SEND_CP\n", dpt->unit, result);
656 splx(ospl);
645 device_printf(dpt->dev,
646 "WARNING: detect_cache() failed (%d) to send "
647 "EATA_CMD_DMA_SEND_CP\n", result);
657 return;
658 }
659 /* Wait for two seconds for a response. This can be slow... */
660 for (ndx = 0;
661 (ndx < 20000) &&
662 !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ);
663 ndx++) {
664 DELAY(50);
665 }
666
667 /* Grab the status and clear interrupts */
668 status = dpt_inb(dpt, HA_RSTATUS);
648 return;
649 }
650 /* Wait for two seconds for a response. This can be slow... */
651 for (ndx = 0;
652 (ndx < 20000) &&
653 !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ);
654 ndx++) {
655 DELAY(50);
656 }
657
658 /* Grab the status and clear interrupts */
659 status = dpt_inb(dpt, HA_RSTATUS);
669 splx(ospl);
670
671 /*
672 * Sanity check
673 */
674 if (buff[0] != 0x33) {
675 return;
676 }
677 bytes = DPT_HCP_LENGTH(buff);
678 param = DPT_HCP_FIRST(buff);
679
680 if (DPT_HCP_CODE(param) != 1) {
681 /*
682 * DPT Log Page layout error
683 */
660
661 /*
662 * Sanity check
663 */
664 if (buff[0] != 0x33) {
665 return;
666 }
667 bytes = DPT_HCP_LENGTH(buff);
668 param = DPT_HCP_FIRST(buff);
669
670 if (DPT_HCP_CODE(param) != 1) {
671 /*
672 * DPT Log Page layout error
673 */
684 printf("dpt%d: NOTICE: Log Page (1) layout error\n",
685 dpt->unit);
674 device_printf(dpt->dev, "NOTICE: Log Page (1) layout error\n");
686 return;
687 }
688 if (!(param[4] & 0x4)) {
689 dpt->cache_type = DPT_NO_CACHE;
690 return;
691 }
692 while (DPT_HCP_CODE(param) != 6) {
693 param = DPT_HCP_NEXT(param);

--- 22 unchanged lines hidden (view full) ---

716 | (param[7] << 16)
717 | (param[8] << 24);
718#endif
719}
720
721static void
722dpt_poll(struct cam_sim *sim)
723{
675 return;
676 }
677 if (!(param[4] & 0x4)) {
678 dpt->cache_type = DPT_NO_CACHE;
679 return;
680 }
681 while (DPT_HCP_CODE(param) != 6) {
682 param = DPT_HCP_NEXT(param);

--- 22 unchanged lines hidden (view full) ---

705 | (param[7] << 16)
706 | (param[8] << 24);
707#endif
708}
709
710static void
711dpt_poll(struct cam_sim *sim)
712{
724 dpt_intr(cam_sim_softc(sim));
713 dpt_intr_locked(cam_sim_softc(sim));
725}
726
727static void
728dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
729{
730 struct dpt_ccb *dccb;
731 union ccb *ccb;
732 struct dpt_softc *dpt;
714}
715
716static void
717dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
718{
719 struct dpt_ccb *dccb;
720 union ccb *ccb;
721 struct dpt_softc *dpt;
733 int s;
734
722
723 if (!dumping)
724 mtx_assert(&dpt->lock, MA_OWNED);
735 dccb = (struct dpt_ccb *)arg;
736 ccb = dccb->ccb;
737 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
738
739 if (error != 0) {
740 if (error != EFBIG)
725 dccb = (struct dpt_ccb *)arg;
726 ccb = dccb->ccb;
727 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
728
729 if (error != 0) {
730 if (error != EFBIG)
741 printf("dpt%d: Unexepected error 0x%x returned from "
742 "bus_dmamap_load\n", dpt->unit, error);
731 device_printf(dpt->dev,
732 "Unexepected error 0x%x returned from "
733 "bus_dmamap_load\n", error);
743 if (ccb->ccb_h.status == CAM_REQ_INPROG) {
744 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
745 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
746 }
747 dptfreeccb(dpt, dccb);
748 xpt_done(ccb);
749 return;
750 }

--- 31 unchanged lines hidden (view full) ---

782
783 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op);
784
785 } else {
786 dccb->eata_ccb.cp_dataDMA = 0;
787 dccb->eata_ccb.cp_datalen = 0;
788 }
789
734 if (ccb->ccb_h.status == CAM_REQ_INPROG) {
735 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
736 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
737 }
738 dptfreeccb(dpt, dccb);
739 xpt_done(ccb);
740 return;
741 }

--- 31 unchanged lines hidden (view full) ---

773
774 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op);
775
776 } else {
777 dccb->eata_ccb.cp_dataDMA = 0;
778 dccb->eata_ccb.cp_datalen = 0;
779 }
780
790 s = splcam();
791
792 /*
793 * Last time we need to check if this CCB needs to
794 * be aborted.
795 */
796 if (ccb->ccb_h.status != CAM_REQ_INPROG) {
797 if (nseg != 0)
798 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
799 dptfreeccb(dpt, dccb);
800 xpt_done(ccb);
781 /*
782 * Last time we need to check if this CCB needs to
783 * be aborted.
784 */
785 if (ccb->ccb_h.status != CAM_REQ_INPROG) {
786 if (nseg != 0)
787 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
788 dptfreeccb(dpt, dccb);
789 xpt_done(ccb);
801 splx(s);
802 return;
803 }
804
805 dccb->state |= DCCB_ACTIVE;
806 ccb->ccb_h.status |= CAM_SIM_QUEUED;
807 LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le);
790 return;
791 }
792
793 dccb->state |= DCCB_ACTIVE;
794 ccb->ccb_h.status |= CAM_SIM_QUEUED;
795 LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le);
808 ccb->ccb_h.timeout_ch =
809 timeout(dpttimeout, (caddr_t)dccb,
810 (ccb->ccb_h.timeout * hz) / 1000);
796 callout_reset(&dccb->timer, (ccb->ccb_h.timeout * hz) / 1000,
797 dpttimeout, dccb);
811 if (dpt_send_eata_command(dpt, &dccb->eata_ccb,
812 dccb->eata_ccb.cp_busaddr,
813 EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) {
814 ccb->ccb_h.status = CAM_NO_HBA; /* HBA dead or just busy?? */
815 if (nseg != 0)
816 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
817 dptfreeccb(dpt, dccb);
818 xpt_done(ccb);
819 }
798 if (dpt_send_eata_command(dpt, &dccb->eata_ccb,
799 dccb->eata_ccb.cp_busaddr,
800 EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) {
801 ccb->ccb_h.status = CAM_NO_HBA; /* HBA dead or just busy?? */
802 if (nseg != 0)
803 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap);
804 dptfreeccb(dpt, dccb);
805 xpt_done(ccb);
806 }
820
821 splx(s);
822}
823
824static void
825dpt_action(struct cam_sim *sim, union ccb *ccb)
826{
827 struct dpt_softc *dpt;
828
829 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n"));
830
831 dpt = (struct dpt_softc *)cam_sim_softc(sim);
807}
808
809static void
810dpt_action(struct cam_sim *sim, union ccb *ccb)
811{
812 struct dpt_softc *dpt;
813
814 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n"));
815
816 dpt = (struct dpt_softc *)cam_sim_softc(sim);
817 mtx_assert(&dpt->lock, MA_OWNED);
832
833 if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) {
834 xpt_print_path(ccb->ccb_h.path);
835 printf("controller is shutdown. Aborting CCB.\n");
836 ccb->ccb_h.status = CAM_NO_HBA;
837 xpt_done(ccb);
838 return;
839 }

--- 11 unchanged lines hidden (view full) ---

851 ccbh = &ccb->ccb_h;
852 /* Max CDB length is 12 bytes */
853 if (csio->cdb_len > 12) {
854 ccb->ccb_h.status = CAM_REQ_INVALID;
855 xpt_done(ccb);
856 return;
857 }
858 if ((dccb = dptgetccb(dpt)) == NULL) {
818
819 if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) {
820 xpt_print_path(ccb->ccb_h.path);
821 printf("controller is shutdown. Aborting CCB.\n");
822 ccb->ccb_h.status = CAM_NO_HBA;
823 xpt_done(ccb);
824 return;
825 }

--- 11 unchanged lines hidden (view full) ---

837 ccbh = &ccb->ccb_h;
838 /* Max CDB length is 12 bytes */
839 if (csio->cdb_len > 12) {
840 ccb->ccb_h.status = CAM_REQ_INVALID;
841 xpt_done(ccb);
842 return;
843 }
844 if ((dccb = dptgetccb(dpt)) == NULL) {
859 int s;
860
861 s = splcam();
862 dpt->resource_shortage = 1;
845 dpt->resource_shortage = 1;
863 splx(s);
864 xpt_freeze_simq(sim, /*count*/1);
865 ccb->ccb_h.status = CAM_REQUEUE_REQ;
866 xpt_done(ccb);
867 return;
868 }
869 eccb = &dccb->eata_ccb;
870
871 /* Link dccb and ccb so we can find one from the other */

--- 57 unchanged lines hidden (view full) ---

929 /* Only use S/G if there is a transfer */
930 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
931 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) {
932 /*
933 * We've been given a pointer
934 * to a single buffer.
935 */
936 if ((ccbh->flags & CAM_DATA_PHYS) == 0) {
846 xpt_freeze_simq(sim, /*count*/1);
847 ccb->ccb_h.status = CAM_REQUEUE_REQ;
848 xpt_done(ccb);
849 return;
850 }
851 eccb = &dccb->eata_ccb;
852
853 /* Link dccb and ccb so we can find one from the other */

--- 57 unchanged lines hidden (view full) ---

911 /* Only use S/G if there is a transfer */
912 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
913 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) {
914 /*
915 * We've been given a pointer
916 * to a single buffer.
917 */
918 if ((ccbh->flags & CAM_DATA_PHYS) == 0) {
937 int s;
938 int error;
939
919 int error;
920
940 s = splsoftvm();
941 error =
942 bus_dmamap_load(dpt->buffer_dmat,
943 dccb->dmamap,
944 csio->data_ptr,
945 csio->dxfer_len,
946 dptexecuteccb,
947 dccb, /*flags*/0);
948 if (error == EINPROGRESS) {
949 /*
950 * So as to maintain ordering,
951 * freeze the controller queue
952 * until our mapping is
953 * returned.
954 */
955 xpt_freeze_simq(sim, 1);
956 dccb->state |= CAM_RELEASE_SIMQ;
957 }
921 error =
922 bus_dmamap_load(dpt->buffer_dmat,
923 dccb->dmamap,
924 csio->data_ptr,
925 csio->dxfer_len,
926 dptexecuteccb,
927 dccb, /*flags*/0);
928 if (error == EINPROGRESS) {
929 /*
930 * So as to maintain ordering,
931 * freeze the controller queue
932 * until our mapping is
933 * returned.
934 */
935 xpt_freeze_simq(sim, 1);
936 dccb->state |= CAM_RELEASE_SIMQ;
937 }
958 splx(s);
959 } else {
960 struct bus_dma_segment seg;
961
962 /* Pointer to physical buffer */
963 seg.ds_addr =
964 (bus_addr_t)csio->data_ptr;
965 seg.ds_len = csio->dxfer_len;
966 dptexecuteccb(dccb, &seg, 1, 0);

--- 133 unchanged lines hidden (view full) ---

1100 break;
1101 }
1102}
1103
1104/*
1105 * This routine will try to send an EATA command to the DPT HBA.
1106 * It will, by default, try 20,000 times, waiting 50us between tries.
1107 * It returns 0 on success and 1 on failure.
938 } else {
939 struct bus_dma_segment seg;
940
941 /* Pointer to physical buffer */
942 seg.ds_addr =
943 (bus_addr_t)csio->data_ptr;
944 seg.ds_len = csio->dxfer_len;
945 dptexecuteccb(dccb, &seg, 1, 0);

--- 133 unchanged lines hidden (view full) ---

1079 break;
1080 }
1081}
1082
1083/*
1084 * This routine will try to send an EATA command to the DPT HBA.
1085 * It will, by default, try 20,000 times, waiting 50us between tries.
1086 * It returns 0 on success and 1 on failure.
1108 * It is assumed to be called at splcam().
1109 */
1110static int
1111dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block,
1112 u_int32_t cmd_busaddr, u_int command, u_int retries,
1113 u_int ifc, u_int code, u_int code2)
1114{
1115 u_int loop;
1116

--- 61 unchanged lines hidden (view full) ---

1178
1179/* ==================== Exported Function definitions =======================*/
1180void
1181dpt_alloc(device_t dev)
1182{
1183 dpt_softc_t *dpt = device_get_softc(dev);
1184 int i;
1185
1087 */
1088static int
1089dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block,
1090 u_int32_t cmd_busaddr, u_int command, u_int retries,
1091 u_int ifc, u_int code, u_int code2)
1092{
1093 u_int loop;
1094

--- 61 unchanged lines hidden (view full) ---

1156
1157/* ==================== Exported Function definitions =======================*/
1158void
1159dpt_alloc(device_t dev)
1160{
1161 dpt_softc_t *dpt = device_get_softc(dev);
1162 int i;
1163
1186 dpt->tag = rman_get_bustag(dpt->io_res);
1187 dpt->bsh = rman_get_bushandle(dpt->io_res) + dpt->io_offset;
1188 dpt->unit = device_get_unit(dev);
1164 mtx_init(&dpt->lock, "dpt", NULL, MTX_DEF);
1189 SLIST_INIT(&dpt->free_dccb_list);
1190 LIST_INIT(&dpt->pending_ccb_list);
1191 for (i = 0; i < MAX_CHANNELS; i++)
1192 dpt->resetlevel[i] = DPT_HA_OK;
1193
1194#ifdef DPT_MEASURE_PERFORMANCE
1195 dpt_reset_performance(dpt);
1196#endif /* DPT_MEASURE_PERFORMANCE */

--- 27 unchanged lines hidden (view full) ---

1224 sg_map->sg_dmamap);
1225 free(sg_map, M_DEVBUF);
1226 }
1227 bus_dma_tag_destroy(dpt->sg_dmat);
1228 }
1229 case 0:
1230 break;
1231 }
1165 SLIST_INIT(&dpt->free_dccb_list);
1166 LIST_INIT(&dpt->pending_ccb_list);
1167 for (i = 0; i < MAX_CHANNELS; i++)
1168 dpt->resetlevel[i] = DPT_HA_OK;
1169
1170#ifdef DPT_MEASURE_PERFORMANCE
1171 dpt_reset_performance(dpt);
1172#endif /* DPT_MEASURE_PERFORMANCE */

--- 27 unchanged lines hidden (view full) ---

1200 sg_map->sg_dmamap);
1201 free(sg_map, M_DEVBUF);
1202 }
1203 bus_dma_tag_destroy(dpt->sg_dmat);
1204 }
1205 case 0:
1206 break;
1207 }
1208 mtx_destroy(&dpt->lock);
1232}
1233
1234int
1235dpt_alloc_resources (device_t dev)
1236{
1237 dpt_softc_t * dpt;
1238 int error;
1239

--- 56 unchanged lines hidden (view full) ---

1296 dpt_ccb_t *dccb;
1297 u_int8_t *strp;
1298 int index;
1299 int i;
1300 int retval;
1301
1302 dpt->init_level = 0;
1303 SLIST_INIT(&dpt->sg_maps);
1209}
1210
1211int
1212dpt_alloc_resources (device_t dev)
1213{
1214 dpt_softc_t * dpt;
1215 int error;
1216

--- 56 unchanged lines hidden (view full) ---

1273 dpt_ccb_t *dccb;
1274 u_int8_t *strp;
1275 int index;
1276 int i;
1277 int retval;
1278
1279 dpt->init_level = 0;
1280 SLIST_INIT(&dpt->sg_maps);
1281 mtx_lock(&dpt->lock);
1304
1305#ifdef DPT_RESET_BOARD
1282
1283#ifdef DPT_RESET_BOARD
1306 printf("dpt%d: resetting HBA\n", dpt->unit);
1284 device_printf(dpt->dev, "resetting HBA\n");
1307 dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET);
1308 DELAY(750000);
1309 /* XXX Shouldn't we poll a status register or something??? */
1310#endif
1311 /* DMA tag for our S/G structures. We allocate in page sized chunks */
1312 if (bus_dma_tag_create( /* parent */ dpt->parent_dmat,
1313 /* alignment */ 1,
1314 /* boundary */ 0,
1315 /* lowaddr */ BUS_SPACE_MAXADDR,
1316 /* highaddr */ BUS_SPACE_MAXADDR,
1317 /* filter */ NULL,
1318 /* filterarg */ NULL,
1319 /* maxsize */ PAGE_SIZE,
1320 /* nsegments */ 1,
1321 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1322 /* flags */ 0,
1285 dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET);
1286 DELAY(750000);
1287 /* XXX Shouldn't we poll a status register or something??? */
1288#endif
1289 /* DMA tag for our S/G structures. We allocate in page sized chunks */
1290 if (bus_dma_tag_create( /* parent */ dpt->parent_dmat,
1291 /* alignment */ 1,
1292 /* boundary */ 0,
1293 /* lowaddr */ BUS_SPACE_MAXADDR,
1294 /* highaddr */ BUS_SPACE_MAXADDR,
1295 /* filter */ NULL,
1296 /* filterarg */ NULL,
1297 /* maxsize */ PAGE_SIZE,
1298 /* nsegments */ 1,
1299 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1300 /* flags */ 0,
1323 /* lockfunc */ busdma_lock_mutex,
1324 /* lockarg */ &Giant,
1301 /* lockfunc */ NULL,
1302 /* lockarg */ NULL,
1325 &dpt->sg_dmat) != 0) {
1326 goto error_exit;
1327 }
1328
1329 dpt->init_level++;
1330
1331 /*
1332 * We allocate our DPT ccbs as a contiguous array of bus dma'able

--- 19 unchanged lines hidden (view full) ---

1352 + offsetof(struct dpt_ccb, sense_data));
1353
1354 /* Okay. Fetch our config */
1355 bzero(&dccb[1], sizeof(conf)); /* data area */
1356 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1357 sizeof(conf), 0xc1, 7, 1);
1358
1359 if (retval != 0) {
1303 &dpt->sg_dmat) != 0) {
1304 goto error_exit;
1305 }
1306
1307 dpt->init_level++;
1308
1309 /*
1310 * We allocate our DPT ccbs as a contiguous array of bus dma'able

--- 19 unchanged lines hidden (view full) ---

1330 + offsetof(struct dpt_ccb, sense_data));
1331
1332 /* Okay. Fetch our config */
1333 bzero(&dccb[1], sizeof(conf)); /* data area */
1334 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1335 sizeof(conf), 0xc1, 7, 1);
1336
1337 if (retval != 0) {
1360 printf("dpt%d: Failed to get board configuration\n", dpt->unit);
1361 return (retval);
1338 device_printf(dpt->dev, "Failed to get board configuration\n");
1339 goto error_exit;
1362 }
1363 bcopy(&dccb[1], &conf, sizeof(conf));
1364
1365 bzero(&dccb[1], sizeof(dpt->board_data));
1366 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1367 sizeof(dpt->board_data), 0, conf.scsi_id0, 0);
1368 if (retval != 0) {
1340 }
1341 bcopy(&dccb[1], &conf, sizeof(conf));
1342
1343 bzero(&dccb[1], sizeof(dpt->board_data));
1344 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1345 sizeof(dpt->board_data), 0, conf.scsi_id0, 0);
1346 if (retval != 0) {
1369 printf("dpt%d: Failed to get inquiry information\n", dpt->unit);
1370 return (retval);
1347 device_printf(dpt->dev, "Failed to get inquiry information\n");
1348 goto error_exit;
1371 }
1372 bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data));
1373
1374 dpt_detect_cache(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1375 (u_int8_t *)&dccb[1]);
1376
1377 switch (ntohl(conf.splen)) {
1378 case DPT_EATA_REVA:

--- 32 unchanged lines hidden (view full) ---

1411
1412 dpt->broken_INQUIRY = FALSE;
1413
1414 dpt->cplen = ntohl(conf.cplen);
1415 dpt->cppadlen = ntohs(conf.cppadlen);
1416 dpt->max_dccbs = ntohs(conf.queuesiz);
1417
1418 if (dpt->max_dccbs > 256) {
1349 }
1350 bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data));
1351
1352 dpt_detect_cache(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t),
1353 (u_int8_t *)&dccb[1]);
1354
1355 switch (ntohl(conf.splen)) {
1356 case DPT_EATA_REVA:

--- 32 unchanged lines hidden (view full) ---

1389
1390 dpt->broken_INQUIRY = FALSE;
1391
1392 dpt->cplen = ntohl(conf.cplen);
1393 dpt->cppadlen = ntohs(conf.cppadlen);
1394 dpt->max_dccbs = ntohs(conf.queuesiz);
1395
1396 if (dpt->max_dccbs > 256) {
1419 printf("dpt%d: Max CCBs reduced from %d to "
1420 "256 due to tag algorithm\n", dpt->unit, dpt->max_dccbs);
1397 device_printf(dpt->dev, "Max CCBs reduced from %d to "
1398 "256 due to tag algorithm\n", dpt->max_dccbs);
1421 dpt->max_dccbs = 256;
1422 }
1423
1424 dpt->hostid[0] = conf.scsi_id0;
1425 dpt->hostid[1] = conf.scsi_id1;
1426 dpt->hostid[2] = conf.scsi_id2;
1427
1428 if (conf.SG_64K)

--- 16 unchanged lines hidden (view full) ---

1445 /* highaddr */ BUS_SPACE_MAXADDR,
1446 /* filter */ NULL,
1447 /* filterarg */ NULL,
1448 /* maxsize */ MAXBSIZE,
1449 /* nsegments */ dpt->sgsize,
1450 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1451 /* flags */ BUS_DMA_ALLOCNOW,
1452 /* lockfunc */ busdma_lock_mutex,
1399 dpt->max_dccbs = 256;
1400 }
1401
1402 dpt->hostid[0] = conf.scsi_id0;
1403 dpt->hostid[1] = conf.scsi_id1;
1404 dpt->hostid[2] = conf.scsi_id2;
1405
1406 if (conf.SG_64K)

--- 16 unchanged lines hidden (view full) ---

1423 /* highaddr */ BUS_SPACE_MAXADDR,
1424 /* filter */ NULL,
1425 /* filterarg */ NULL,
1426 /* maxsize */ MAXBSIZE,
1427 /* nsegments */ dpt->sgsize,
1428 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1429 /* flags */ BUS_DMA_ALLOCNOW,
1430 /* lockfunc */ busdma_lock_mutex,
1453 /* lockarg */ &Giant,
1431 /* lockarg */ &dpt->lock,
1454 &dpt->buffer_dmat) != 0) {
1432 &dpt->buffer_dmat) != 0) {
1455 printf("dpt: bus_dma_tag_create(...,dpt->buffer_dmat) failed\n");
1433 device_printf(dpt->dev,
1434 "bus_dma_tag_create(...,dpt->buffer_dmat) failed\n");
1456 goto error_exit;
1457 }
1458
1459 dpt->init_level++;
1460
1461 /* DMA tag for our ccb structures and interrupt status packet */
1462 if (bus_dma_tag_create( /* parent */ dpt->parent_dmat,
1463 /* alignment */ 1,
1464 /* boundary */ 0,
1465 /* lowaddr */ BUS_SPACE_MAXADDR,
1466 /* highaddr */ BUS_SPACE_MAXADDR,
1467 /* filter */ NULL,
1468 /* filterarg */ NULL,
1469 /* maxsize */ (dpt->max_dccbs *
1470 sizeof(struct dpt_ccb)) +
1471 sizeof(dpt_sp_t),
1472 /* nsegments */ 1,
1473 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1474 /* flags */ 0,
1435 goto error_exit;
1436 }
1437
1438 dpt->init_level++;
1439
1440 /* DMA tag for our ccb structures and interrupt status packet */
1441 if (bus_dma_tag_create( /* parent */ dpt->parent_dmat,
1442 /* alignment */ 1,
1443 /* boundary */ 0,
1444 /* lowaddr */ BUS_SPACE_MAXADDR,
1445 /* highaddr */ BUS_SPACE_MAXADDR,
1446 /* filter */ NULL,
1447 /* filterarg */ NULL,
1448 /* maxsize */ (dpt->max_dccbs *
1449 sizeof(struct dpt_ccb)) +
1450 sizeof(dpt_sp_t),
1451 /* nsegments */ 1,
1452 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
1453 /* flags */ 0,
1475 /* lockfunc */ busdma_lock_mutex,
1476 /* lockarg */ &Giant,
1454 /* lockfunc */ NULL,
1455 /* lockarg */ NULL,
1477 &dpt->dccb_dmat) != 0) {
1456 &dpt->dccb_dmat) != 0) {
1478 printf("dpt: bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
1457 device_printf(dpt->dev,
1458 "bus_dma_tag_create(...,dpt->dccb_dmat) failed\n");
1479 goto error_exit;
1480 }
1481
1482 dpt->init_level++;
1483
1484 /* Allocation for our ccbs and interrupt status packet */
1485 if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs,
1486 BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) {
1459 goto error_exit;
1460 }
1461
1462 dpt->init_level++;
1463
1464 /* Allocation for our ccbs and interrupt status packet */
1465 if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs,
1466 BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) {
1487 printf("dpt: bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
1467 device_printf(dpt->dev,
1468 "bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n");
1488 goto error_exit;
1489 }
1490
1491 dpt->init_level++;
1492
1493 /* And permanently map them */
1494 bus_dmamap_load(dpt->dccb_dmat, dpt->dccb_dmamap,
1495 dpt->dpt_dccbs,

--- 9 unchanged lines hidden (view full) ---

1505
1506 dpt->sp = (dpt_sp_t*)&dpt->dpt_dccbs[dpt->max_dccbs];
1507 dpt->sp_physaddr = dpt->dpt_ccb_busbase
1508 + (dpt->max_dccbs * sizeof(dpt_ccb_t));
1509 dpt->init_level++;
1510
1511 /* Allocate our first batch of ccbs */
1512 if (dptallocccbs(dpt) == 0) {
1469 goto error_exit;
1470 }
1471
1472 dpt->init_level++;
1473
1474 /* And permanently map them */
1475 bus_dmamap_load(dpt->dccb_dmat, dpt->dccb_dmamap,
1476 dpt->dpt_dccbs,

--- 9 unchanged lines hidden (view full) ---

1486
1487 dpt->sp = (dpt_sp_t*)&dpt->dpt_dccbs[dpt->max_dccbs];
1488 dpt->sp_physaddr = dpt->dpt_ccb_busbase
1489 + (dpt->max_dccbs * sizeof(dpt_ccb_t));
1490 dpt->init_level++;
1491
1492 /* Allocate our first batch of ccbs */
1493 if (dptallocccbs(dpt) == 0) {
1513 printf("dpt: dptallocccbs(dpt) == 0\n");
1494 device_printf(dpt->dev, "dptallocccbs(dpt) == 0\n");
1495 mtx_unlock(&dpt->lock);
1514 return (2);
1515 }
1516
1517 /* Prepare for Target Mode */
1518 dpt->target_mode_enabled = 1;
1519
1520 /* Nuke excess spaces from inquiry information */
1521 strp = dpt->board_data.vendor;
1522 for (i = 0; i < sizeof(string_sizes); i++) {
1523 index = string_sizes[i] - 1;
1524 while (index && (strp[index] == ' '))
1525 strp[index--] = '\0';
1526 strp += string_sizes[i];
1527 }
1528
1496 return (2);
1497 }
1498
1499 /* Prepare for Target Mode */
1500 dpt->target_mode_enabled = 1;
1501
1502 /* Nuke excess spaces from inquiry information */
1503 strp = dpt->board_data.vendor;
1504 for (i = 0; i < sizeof(string_sizes); i++) {
1505 index = string_sizes[i] - 1;
1506 while (index && (strp[index] == ' '))
1507 strp[index--] = '\0';
1508 strp += string_sizes[i];
1509 }
1510
1529 printf("dpt%d: %.8s %.16s FW Rev. %.4s, ",
1530 dpt->unit, dpt->board_data.vendor,
1511 device_printf(dpt->dev, "%.8s %.16s FW Rev. %.4s, ",
1512 dpt->board_data.vendor,
1531 dpt->board_data.modelNum, dpt->board_data.firmware);
1532
1533 printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : "");
1534
1535 if (dpt->cache_type != DPT_NO_CACHE
1536 && dpt->cache_size != 0) {
1537 printf("%s Cache, ",
1538 dpt->cache_type == DPT_CACHE_WRITETHROUGH
1539 ? "Write-Through" : "Write-Back");
1540 }
1541
1542 printf("%d CCBs\n", dpt->max_dccbs);
1513 dpt->board_data.modelNum, dpt->board_data.firmware);
1514
1515 printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : "");
1516
1517 if (dpt->cache_type != DPT_NO_CACHE
1518 && dpt->cache_size != 0) {
1519 printf("%s Cache, ",
1520 dpt->cache_type == DPT_CACHE_WRITETHROUGH
1521 ? "Write-Through" : "Write-Back");
1522 }
1523
1524 printf("%d CCBs\n", dpt->max_dccbs);
1525 mtx_unlock(&dpt->lock);
1543 return (0);
1544
1545error_exit:
1526 return (0);
1527
1528error_exit:
1529 mtx_unlock(&dpt->lock);
1546 return (1);
1547}
1548
1549int
1550dpt_attach(dpt_softc_t *dpt)
1551{
1552 struct cam_devq *devq;
1553 int i;
1554
1555 /*
1556 * Create the device queue for our SIM.
1557 */
1558 devq = cam_simq_alloc(dpt->max_dccbs);
1559 if (devq == NULL)
1560 return (0);
1561
1530 return (1);
1531}
1532
1533int
1534dpt_attach(dpt_softc_t *dpt)
1535{
1536 struct cam_devq *devq;
1537 int i;
1538
1539 /*
1540 * Create the device queue for our SIM.
1541 */
1542 devq = cam_simq_alloc(dpt->max_dccbs);
1543 if (devq == NULL)
1544 return (0);
1545
1546 mtx_lock(&dpt->lock);
1562 for (i = 0; i < dpt->channels; i++) {
1563 /*
1564 * Construct our SIM entry
1565 */
1566 dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt",
1547 for (i = 0; i < dpt->channels; i++) {
1548 /*
1549 * Construct our SIM entry
1550 */
1551 dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt",
1567 dpt, dpt->unit, &Giant,
1552 dpt, device_get_unit(dpt->dev), &dpt->lock,
1568 /*untagged*/2,
1569 /*tagged*/dpt->max_dccbs, devq);
1570 if (dpt->sims[i] == NULL) {
1571 if (i == 0)
1572 cam_simq_free(devq);
1573 else
1574 printf( "%s(): Unable to attach bus %d "
1575 "due to resource shortage\n",

--- 13 unchanged lines hidden (view full) ---

1589 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1590 xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
1591 cam_sim_free(dpt->sims[i], /*free_devq*/i == 0);
1592 dpt->sims[i] = NULL;
1593 break;
1594 }
1595
1596 }
1553 /*untagged*/2,
1554 /*tagged*/dpt->max_dccbs, devq);
1555 if (dpt->sims[i] == NULL) {
1556 if (i == 0)
1557 cam_simq_free(devq);
1558 else
1559 printf( "%s(): Unable to attach bus %d "
1560 "due to resource shortage\n",

--- 13 unchanged lines hidden (view full) ---

1574 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1575 xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
1576 cam_sim_free(dpt->sims[i], /*free_devq*/i == 0);
1577 dpt->sims[i] = NULL;
1578 break;
1579 }
1580
1581 }
1582 mtx_unlock(&dpt->lock);
1597 if (i > 0)
1598 EVENTHANDLER_REGISTER(shutdown_final, dptshutdown,
1599 dpt, SHUTDOWN_PRI_DEFAULT);
1600 return (i);
1601}
1602
1603int
1604dpt_detach (device_t dev)
1605{
1606 struct dpt_softc * dpt;
1607 int i;
1608
1609 dpt = device_get_softc(dev);
1610
1583 if (i > 0)
1584 EVENTHANDLER_REGISTER(shutdown_final, dptshutdown,
1585 dpt, SHUTDOWN_PRI_DEFAULT);
1586 return (i);
1587}
1588
1589int
1590dpt_detach (device_t dev)
1591{
1592 struct dpt_softc * dpt;
1593 int i;
1594
1595 dpt = device_get_softc(dev);
1596
1597 mtx_lock(&dpt->lock);
1611 for (i = 0; i < dpt->channels; i++) {
1612#if 0
1613 xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL);
1614#endif
1615 xpt_free_path(dpt->paths[i]);
1616 xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
1617 cam_sim_free(dpt->sims[i], /*free_devq*/TRUE);
1618 }
1598 for (i = 0; i < dpt->channels; i++) {
1599#if 0
1600 xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL);
1601#endif
1602 xpt_free_path(dpt->paths[i]);
1603 xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
1604 cam_sim_free(dpt->sims[i], /*free_devq*/TRUE);
1605 }
1606 mtx_unlock(&dpt->lock);
1619
1620 dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT);
1621
1622 dpt_release_resources(dev);
1623
1624 dpt_free(dpt);
1625
1626 return (0);
1627}
1628
1629/*
1630 * This is the interrupt handler for the DPT driver.
1631 */
1632void
1633dpt_intr(void *arg)
1634{
1635 dpt_softc_t *dpt;
1607
1608 dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT);
1609
1610 dpt_release_resources(dev);
1611
1612 dpt_free(dpt);
1613
1614 return (0);
1615}
1616
1617/*
1618 * This is the interrupt handler for the DPT driver.
1619 */
1620void
1621dpt_intr(void *arg)
1622{
1623 dpt_softc_t *dpt;
1624
1625 dpt = arg;
1626 mtx_lock(&dpt->lock);
1627 dpt_intr_locked(dpt);
1628 mtx_unlock(&dpt->lock);
1629}
1630
1631void
1632dpt_intr_locked(dpt_softc_t *dpt)
1633{
1636 dpt_ccb_t *dccb;
1637 union ccb *ccb;
1638 u_int status;
1639 u_int aux_status;
1640 u_int hba_stat;
1641 u_int scsi_stat;
1642 u_int32_t residue_len; /* Number of bytes not transferred */
1643
1634 dpt_ccb_t *dccb;
1635 union ccb *ccb;
1636 u_int status;
1637 u_int aux_status;
1638 u_int hba_stat;
1639 u_int scsi_stat;
1640 u_int32_t residue_len; /* Number of bytes not transferred */
1641
1644 dpt = (dpt_softc_t *)arg;
1645
1646 /* First order of business is to check if this interrupt is for us */
1647 while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) {
1648
1649 /*
1650 * What we want to do now, is to capture the status, all of it,
1651 * move it where it belongs, wake up whoever sleeps waiting to
1652 * process this result, and get out of here.
1653 */
1654 if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase
1655 || dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) {
1642 /* First order of business is to check if this interrupt is for us */
1643 while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) {
1644
1645 /*
1646 * What we want to do now, is to capture the status, all of it,
1647 * move it where it belongs, wake up whoever sleeps waiting to
1648 * process this result, and get out of here.
1649 */
1650 if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase
1651 || dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) {
1656 printf("Encountered bogus status packet\n");
1652 device_printf(dpt->dev,
1653 "Encountered bogus status packet\n");
1657 status = dpt_inb(dpt, HA_RSTATUS);
1658 return;
1659 }
1660
1661 dccb = dptccbptov(dpt, dpt->sp->ccb_busaddr);
1662
1663 dpt->sp->ccb_busaddr = ~0;
1664
1665 /* Ignore status packets with EOC not set */
1666 if (dpt->sp->EOC == 0) {
1654 status = dpt_inb(dpt, HA_RSTATUS);
1655 return;
1656 }
1657
1658 dccb = dptccbptov(dpt, dpt->sp->ccb_busaddr);
1659
1660 dpt->sp->ccb_busaddr = ~0;
1661
1662 /* Ignore status packets with EOC not set */
1663 if (dpt->sp->EOC == 0) {
1667 printf("dpt%d ERROR: Request %d received with "
1664 device_printf(dpt->dev,
1665 "ERROR: Request %d received with "
1668 "clear EOC.\n Marking as LOST.\n",
1666 "clear EOC.\n Marking as LOST.\n",
1669 dpt->unit, dccb->transaction_id);
1667 dccb->transaction_id);
1670
1671#ifdef DPT_HANDLE_TIMEOUTS
1672 dccb->state |= DPT_CCB_STATE_MARKED_LOST;
1673#endif
1674 /* This CLEARS the interrupt! */
1675 status = dpt_inb(dpt, HA_RSTATUS);
1676 continue;
1677 }

--- 13 unchanged lines hidden (view full) ---

1691 if ((status = dpt_inb(dpt, HA_RSTATUS)) & HA_SERROR) {
1692 /*
1693 * Error Condition. Check for magic cookie. Exit
1694 * this test on earliest sign of non-reset condition
1695 */
1696
1697 /* Check that this is not a board reset interrupt */
1698 if (dpt_just_reset(dpt)) {
1668
1669#ifdef DPT_HANDLE_TIMEOUTS
1670 dccb->state |= DPT_CCB_STATE_MARKED_LOST;
1671#endif
1672 /* This CLEARS the interrupt! */
1673 status = dpt_inb(dpt, HA_RSTATUS);
1674 continue;
1675 }

--- 13 unchanged lines hidden (view full) ---

1689 if ((status = dpt_inb(dpt, HA_RSTATUS)) & HA_SERROR) {
1690 /*
1691 * Error Condition. Check for magic cookie. Exit
1692 * this test on earliest sign of non-reset condition
1693 */
1694
1695 /* Check that this is not a board reset interrupt */
1696 if (dpt_just_reset(dpt)) {
1699 printf("dpt%d: HBA rebooted.\n"
1697 device_printf(dpt->dev, "HBA rebooted.\n"
1700 " All transactions should be "
1698 " All transactions should be "
1701 "resubmitted\n",
1702 dpt->unit);
1699 "resubmitted\n");
1703
1700
1704 printf("dpt%d: >>---->> This is incomplete, "
1705 "fix me.... <<----<<", dpt->unit);
1701 device_printf(dpt->dev,
1702 ">>---->> This is incomplete, "
1703 "fix me.... <<----<<");
1706 panic("DPT Rebooted");
1707
1708 }
1709 }
1710 /* Process CCB */
1711 ccb = dccb->ccb;
1704 panic("DPT Rebooted");
1705
1706 }
1707 }
1708 /* Process CCB */
1709 ccb = dccb->ccb;
1712 untimeout(dpttimeout, dccb, ccb->ccb_h.timeout_ch);
1710 callout_stop(&dccb->timer);
1713 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1714 bus_dmasync_op_t op;
1715
1716 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1717 op = BUS_DMASYNC_POSTREAD;
1718 else
1719 op = BUS_DMASYNC_POSTWRITE;
1720 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op);

--- 77 unchanged lines hidden (view full) ---

1798 * from these conditions
1799 */
1800 ccb->ccb_h.status = CAM_NO_HBA;
1801 break;
1802 case HA_RSENSE_FAIL:
1803 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
1804 break;
1805 default:
1711 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1712 bus_dmasync_op_t op;
1713
1714 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1715 op = BUS_DMASYNC_POSTREAD;
1716 else
1717 op = BUS_DMASYNC_POSTWRITE;
1718 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op);

--- 77 unchanged lines hidden (view full) ---

1796 * from these conditions
1797 */
1798 ccb->ccb_h.status = CAM_NO_HBA;
1799 break;
1800 case HA_RSENSE_FAIL:
1801 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
1802 break;
1803 default:
1806 printf("dpt%d: Undocumented Error %x\n", dpt->unit, hba_stat);
1804 device_printf(dpt->dev, "Undocumented Error %x\n", hba_stat);
1807 printf("Please mail this message to shimon@simon-shapiro.org\n");
1808 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1809 break;
1810 }
1811 dptfreeccb(dpt, dccb);
1812 xpt_done(ccb);
1813}
1814
1815static void
1816dpttimeout(void *arg)
1817{
1818 struct dpt_ccb *dccb;
1819 union ccb *ccb;
1820 struct dpt_softc *dpt;
1805 printf("Please mail this message to shimon@simon-shapiro.org\n");
1806 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1807 break;
1808 }
1809 dptfreeccb(dpt, dccb);
1810 xpt_done(ccb);
1811}
1812
1813static void
1814dpttimeout(void *arg)
1815{
1816 struct dpt_ccb *dccb;
1817 union ccb *ccb;
1818 struct dpt_softc *dpt;
1821 int s;
1822
1823 dccb = (struct dpt_ccb *)arg;
1824 ccb = dccb->ccb;
1825 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
1819
1820 dccb = (struct dpt_ccb *)arg;
1821 ccb = dccb->ccb;
1822 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr;
1823 mtx_assert(&dpt->lock, MA_OWNED);
1826 xpt_print_path(ccb->ccb_h.path);
1827 printf("CCB %p - timed out\n", (void *)dccb);
1828
1824 xpt_print_path(ccb->ccb_h.path);
1825 printf("CCB %p - timed out\n", (void *)dccb);
1826
1829 s = splcam();
1830
1831 /*
1832 * Try to clear any pending jobs. FreeBSD will lose interrupts,
1833 * leaving the controller suspended, and commands timed-out.
1834 * By calling the interrupt handler, any command thus stuck will be
1835 * completed.
1836 */
1827 /*
1828 * Try to clear any pending jobs. FreeBSD will lose interrupts,
1829 * leaving the controller suspended, and commands timed-out.
1830 * By calling the interrupt handler, any command thus stuck will be
1831 * completed.
1832 */
1837 dpt_intr(dpt);
1833 dpt_intr_locked(dpt);
1838
1839 if ((dccb->state & DCCB_ACTIVE) == 0) {
1840 xpt_print_path(ccb->ccb_h.path);
1841 printf("CCB %p - timed out CCB already completed\n",
1842 (void *)dccb);
1834
1835 if ((dccb->state & DCCB_ACTIVE) == 0) {
1836 xpt_print_path(ccb->ccb_h.path);
1837 printf("CCB %p - timed out CCB already completed\n",
1838 (void *)dccb);
1843 splx(s);
1844 return;
1845 }
1846
1847 /* Abort this particular command. Leave all others running */
1848 dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr,
1849 /*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0);
1850 ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1839 return;
1840 }
1841
1842 /* Abort this particular command. Leave all others running */
1843 dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr,
1844 /*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0);
1845 ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1851 splx(s);
1852}
1853
1854/*
1855 * Shutdown the controller and ensure that the cache is completely flushed.
1856 * Called from the shutdown_final event after all disk access has completed.
1857 */
1858static void
1859dptshutdown(void *arg, int howto)
1860{
1861 dpt_softc_t *dpt;
1862
1863 dpt = (dpt_softc_t *)arg;
1864
1846}
1847
1848/*
1849 * Shutdown the controller and ensure that the cache is completely flushed.
1850 * Called from the shutdown_final event after all disk access has completed.
1851 */
1852static void
1853dptshutdown(void *arg, int howto)
1854{
1855 dpt_softc_t *dpt;
1856
1857 dpt = (dpt_softc_t *)arg;
1858
1865 printf("dpt%d: Shutting down (mode %x) HBA. Please wait...\n",
1866 dpt->unit, howto);
1859 device_printf(dpt->dev,
1860 "Shutting down (mode %x) HBA. Please wait...\n", howto);
1867
1868 /*
1869 * What we do for a shutdown, is give the DPT early power loss warning
1870 */
1861
1862 /*
1863 * What we do for a shutdown, is give the DPT early power loss warning
1864 */
1865 mtx_lock(&dpt->lock);
1871 dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0);
1866 dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0);
1867 mtx_unlock(&dpt->lock);
1872 DELAY(1000 * 1000 * 5);
1868 DELAY(1000 * 1000 * 5);
1873 printf("dpt%d: Controller was warned of shutdown and is now "
1874 "disabled\n", dpt->unit);
1869 device_printf(dpt->dev, "Controller was warned of shutdown and is now "
1870 "disabled\n");
1875}
1876
1877/*============================================================================*/
1878
1879#if 0
1880#ifdef DPT_RESET_HBA
1881
1882/*
1883** Function name : dpt_reset_hba
1884**
1885** Description : Reset the HBA and properly discard all pending work
1886** Input : Softc
1887** Output : Nothing
1888*/
1889static void
1890dpt_reset_hba(dpt_softc_t *dpt)
1891{
1892 eata_ccb_t *ccb;
1871}
1872
1873/*============================================================================*/
1874
1875#if 0
1876#ifdef DPT_RESET_HBA
1877
1878/*
1879** Function name : dpt_reset_hba
1880**
1881** Description : Reset the HBA and properly discard all pending work
1882** Input : Softc
1883** Output : Nothing
1884*/
1885static void
1886dpt_reset_hba(dpt_softc_t *dpt)
1887{
1888 eata_ccb_t *ccb;
1893 int ospl;
1894 dpt_ccb_t dccb, *dccbp;
1895 int result;
1896 struct scsi_xfer *xs;
1889 dpt_ccb_t dccb, *dccbp;
1890 int result;
1891 struct scsi_xfer *xs;
1897
1892
1893 mtx_assert(&dpt->lock, MA_OWNED);
1894
1898 /* Prepare a control block. The SCSI command part is immaterial */
1899 dccb.xs = NULL;
1900 dccb.flags = 0;
1901 dccb.state = DPT_CCB_STATE_NEW;
1902 dccb.std_callback = NULL;
1903 dccb.wrbuff_callback = NULL;
1904
1905 ccb = &dccb.eata_ccb;

--- 9 unchanged lines hidden (view full) ---

1915 ccb->cp_statDMA = htonl(vtophys(&ccb->cp_statDMA));
1916 ccb->cp_reqDMA = htonl(vtophys(&ccb->cp_reqDMA));
1917 ccb->cp_viraddr = (u_int32_t) & ccb;
1918
1919 ccb->cp_msg[0] = HA_IDENTIFY_MSG | HA_DISCO_RECO;
1920 ccb->cp_scsi_cmd = 0; /* Should be ignored */
1921
1922 /* Lock up the submitted queue. We are very persistant here */
1895 /* Prepare a control block. The SCSI command part is immaterial */
1896 dccb.xs = NULL;
1897 dccb.flags = 0;
1898 dccb.state = DPT_CCB_STATE_NEW;
1899 dccb.std_callback = NULL;
1900 dccb.wrbuff_callback = NULL;
1901
1902 ccb = &dccb.eata_ccb;

--- 9 unchanged lines hidden (view full) ---

1912 ccb->cp_statDMA = htonl(vtophys(&ccb->cp_statDMA));
1913 ccb->cp_reqDMA = htonl(vtophys(&ccb->cp_reqDMA));
1914 ccb->cp_viraddr = (u_int32_t) & ccb;
1915
1916 ccb->cp_msg[0] = HA_IDENTIFY_MSG | HA_DISCO_RECO;
1917 ccb->cp_scsi_cmd = 0; /* Should be ignored */
1918
1919 /* Lock up the submitted queue. We are very persistant here */
1923 ospl = splcam();
1924 while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) {
1925 DELAY(100);
1926 }
1927
1928 dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE;
1920 while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) {
1921 DELAY(100);
1922 }
1923
1924 dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE;
1929 splx(ospl);
1930
1931 /* Send the RESET message */
1932 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
1933 EATA_CMD_RESET, 0, 0, 0, 0)) != 0) {
1925
1926 /* Send the RESET message */
1927 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
1928 EATA_CMD_RESET, 0, 0, 0, 0)) != 0) {
1934 printf("dpt%d: Failed to send the RESET message.\n"
1935 " Trying cold boot (ouch!)\n", dpt->unit);
1929 device_printf(dpt->dev, "Failed to send the RESET message.\n"
1930 " Trying cold boot (ouch!)\n");
1936
1937
1938 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
1939 EATA_COLD_BOOT, 0, 0,
1940 0, 0)) != 0) {
1931
1932
1933 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb,
1934 EATA_COLD_BOOT, 0, 0,
1935 0, 0)) != 0) {
1941 panic("dpt%d: Faild to cold boot the HBA\n",
1942 dpt->unit);
1936 panic("%s: Faild to cold boot the HBA\n",
1937 device_get_nameunit(dpt->dev));
1943 }
1944#ifdef DPT_MEASURE_PERFORMANCE
1945 dpt->performance.cold_boots++;
1946#endif /* DPT_MEASURE_PERFORMANCE */
1947 }
1948
1949#ifdef DPT_MEASURE_PERFORMANCE
1950 dpt->performance.warm_starts++;
1951#endif /* DPT_MEASURE_PERFORMANCE */
1952
1938 }
1939#ifdef DPT_MEASURE_PERFORMANCE
1940 dpt->performance.cold_boots++;
1941#endif /* DPT_MEASURE_PERFORMANCE */
1942 }
1943
1944#ifdef DPT_MEASURE_PERFORMANCE
1945 dpt->performance.warm_starts++;
1946#endif /* DPT_MEASURE_PERFORMANCE */
1947
1953 printf("dpt%d: Aborting pending requests. O/S should re-submit\n",
1954 dpt->unit);
1948 device_printf(dpt->dev,
1949 "Aborting pending requests. O/S should re-submit\n");
1955
1956 while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) {
1957 struct scsi_xfer *xs = dccbp->xs;
1958
1959 /* Not all transactions have xs structs */
1960 if (xs != NULL) {
1961 /* Tell the kernel proper this did not complete well */
1962 xs->error |= XS_SELTIMEOUT;
1963 xs->flags |= SCSI_ITSDONE;
1964 scsi_done(xs);
1965 }
1966
1967 dpt_Qremove_submitted(dpt, dccbp);
1968
1969 /* Remember, Callbacks are NOT in the standard queue */
1970 if (dccbp->std_callback != NULL) {
1971 (dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel,
1972 dccbp);
1973 } else {
1950
1951 while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) {
1952 struct scsi_xfer *xs = dccbp->xs;
1953
1954 /* Not all transactions have xs structs */
1955 if (xs != NULL) {
1956 /* Tell the kernel proper this did not complete well */
1957 xs->error |= XS_SELTIMEOUT;
1958 xs->flags |= SCSI_ITSDONE;
1959 scsi_done(xs);
1960 }
1961
1962 dpt_Qremove_submitted(dpt, dccbp);
1963
1964 /* Remember, Callbacks are NOT in the standard queue */
1965 if (dccbp->std_callback != NULL) {
1966 (dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel,
1967 dccbp);
1968 } else {
1974 ospl = splcam();
1975 dpt_Qpush_free(dpt, dccbp);
1969 dpt_Qpush_free(dpt, dccbp);
1976 splx(ospl);
1977 }
1978 }
1979
1970 }
1971 }
1972
1980 printf("dpt%d: reset done aborting all pending commands\n", dpt->unit);
1973 device_printf(dpt->dev, "reset done aborting all pending commands\n");
1981 dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE;
1982}
1983
1984#endif /* DPT_RESET_HBA */
1985
1986/*
1987 * Build a Command Block for target mode READ/WRITE BUFFER,
1988 * with the ``sync'' bit ON.

--- 5 unchanged lines hidden (view full) ---

1994 */
1995
1996static void
1997dpt_target_ccb(dpt_softc_t * dpt, int bus, u_int8_t target, u_int8_t lun,
1998 dpt_ccb_t * ccb, int mode, u_int8_t command,
1999 u_int16_t length, u_int16_t offset)
2000{
2001 eata_ccb_t *cp;
1974 dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE;
1975}
1976
1977#endif /* DPT_RESET_HBA */
1978
1979/*
1980 * Build a Command Block for target mode READ/WRITE BUFFER,
1981 * with the ``sync'' bit ON.

--- 5 unchanged lines hidden (view full) ---

1987 */
1988
1989static void
1990dpt_target_ccb(dpt_softc_t * dpt, int bus, u_int8_t target, u_int8_t lun,
1991 dpt_ccb_t * ccb, int mode, u_int8_t command,
1992 u_int16_t length, u_int16_t offset)
1993{
1994 eata_ccb_t *cp;
2002 int ospl;
2003
1995
1996 mtx_assert(&dpt->lock, MA_OWNED);
2004 if ((length + offset) > DPT_MAX_TARGET_MODE_BUFFER_SIZE) {
1997 if ((length + offset) > DPT_MAX_TARGET_MODE_BUFFER_SIZE) {
2005 printf("dpt%d: Length of %d, and offset of %d are wrong\n",
2006 dpt->unit, length, offset);
1998 device_printf(dpt->dev,
1999 "Length of %d, and offset of %d are wrong\n",
2000 length, offset);
2007 length = DPT_MAX_TARGET_MODE_BUFFER_SIZE;
2008 offset = 0;
2009 }
2010 ccb->xs = NULL;
2011 ccb->flags = 0;
2012 ccb->state = DPT_CCB_STATE_NEW;
2013 ccb->std_callback = (ccb_callback) dpt_target_done;
2014 ccb->wrbuff_callback = NULL;

--- 27 unchanged lines hidden (view full) ---

2042 cp->cp_cdb[9] = 0; /* No sync, no match bits */
2043
2044 /*
2045 * This could be optimized to live in dpt_register_buffer.
2046 * We keep it here, just in case the kernel decides to reallocate pages
2047 */
2048 if (dpt_scatter_gather(dpt, ccb, DPT_RW_BUFFER_SIZE,
2049 dpt->rw_buffer[bus][target][lun])) {
2001 length = DPT_MAX_TARGET_MODE_BUFFER_SIZE;
2002 offset = 0;
2003 }
2004 ccb->xs = NULL;
2005 ccb->flags = 0;
2006 ccb->state = DPT_CCB_STATE_NEW;
2007 ccb->std_callback = (ccb_callback) dpt_target_done;
2008 ccb->wrbuff_callback = NULL;

--- 27 unchanged lines hidden (view full) ---

2036 cp->cp_cdb[9] = 0; /* No sync, no match bits */
2037
2038 /*
2039 * This could be optimized to live in dpt_register_buffer.
2040 * We keep it here, just in case the kernel decides to reallocate pages
2041 */
2042 if (dpt_scatter_gather(dpt, ccb, DPT_RW_BUFFER_SIZE,
2043 dpt->rw_buffer[bus][target][lun])) {
2050 printf("dpt%d: Failed to setup Scatter/Gather for "
2051 "Target-Mode buffer\n", dpt->unit);
2044 device_printf(dpt->dev, "Failed to setup Scatter/Gather for "
2045 "Target-Mode buffer\n");
2052 }
2053}
2054
2055/* Setup a target mode READ command */
2056
2057static void
2058dpt_set_target(int redo, dpt_softc_t * dpt,
2059 u_int8_t bus, u_int8_t target, u_int8_t lun, int mode,
2060 u_int16_t length, u_int16_t offset, dpt_ccb_t * ccb)
2061{
2046 }
2047}
2048
2049/* Setup a target mode READ command */
2050
2051static void
2052dpt_set_target(int redo, dpt_softc_t * dpt,
2053 u_int8_t bus, u_int8_t target, u_int8_t lun, int mode,
2054 u_int16_t length, u_int16_t offset, dpt_ccb_t * ccb)
2055{
2062 int ospl;
2063
2056
2057 mtx_assert(&dpt->lock, MA_OWNED);
2064 if (dpt->target_mode_enabled) {
2058 if (dpt->target_mode_enabled) {
2065 ospl = splcam();
2066
2067 if (!redo)
2068 dpt_target_ccb(dpt, bus, target, lun, ccb, mode,
2069 SCSI_TM_READ_BUFFER, length, offset);
2070
2071 ccb->transaction_id = ++dpt->commands_processed;
2072
2073#ifdef DPT_MEASURE_PERFORMANCE
2074 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++;
2075 ccb->command_started = microtime_now;
2076#endif
2077 dpt_Qadd_waiting(dpt, ccb);
2078 dpt_sched_queue(dpt);
2059 if (!redo)
2060 dpt_target_ccb(dpt, bus, target, lun, ccb, mode,
2061 SCSI_TM_READ_BUFFER, length, offset);
2062
2063 ccb->transaction_id = ++dpt->commands_processed;
2064
2065#ifdef DPT_MEASURE_PERFORMANCE
2066 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++;
2067 ccb->command_started = microtime_now;
2068#endif
2069 dpt_Qadd_waiting(dpt, ccb);
2070 dpt_sched_queue(dpt);
2079
2080 splx(ospl);
2081 } else {
2071 } else {
2082 printf("dpt%d: Target Mode Request, but Target Mode is OFF\n",
2083 dpt->unit);
2072 device_printf(dpt->dev,
2073 "Target Mode Request, but Target Mode is OFF\n");
2084 }
2085}
2086
2087/*
2088 * Schedule a buffer to be sent to another target.
2089 * The work will be scheduled and the callback provided will be called when
2090 * the work is actually done.
2091 *
2092 * Please NOTE: ``Anyone'' can send a buffer, but only registered clients
2093 * get notified of receipt of buffers.
2094 */
2095
2096int
2097dpt_send_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
2098 u_int8_t mode, u_int16_t length, u_int16_t offset, void *data,
2099 buff_wr_done callback)
2100{
2101 dpt_softc_t *dpt;
2102 dpt_ccb_t *ccb = NULL;
2074 }
2075}
2076
2077/*
2078 * Schedule a buffer to be sent to another target.
2079 * The work will be scheduled and the callback provided will be called when
2080 * the work is actually done.
2081 *
2082 * Please NOTE: ``Anyone'' can send a buffer, but only registered clients
2083 * get notified of receipt of buffers.
2084 */
2085
2086int
2087dpt_send_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
2088 u_int8_t mode, u_int16_t length, u_int16_t offset, void *data,
2089 buff_wr_done callback)
2090{
2091 dpt_softc_t *dpt;
2092 dpt_ccb_t *ccb = NULL;
2103 int ospl;
2104
2105 /* This is an external call. Be a bit paranoid */
2093
2094 /* This is an external call. Be a bit paranoid */
2106 for (dpt = TAILQ_FIRST(&dpt_softc_list);
2107 dpt != NULL;
2108 dpt = TAILQ_NEXT(dpt, links)) {
2109 if (dpt->unit == unit)
2110 goto valid_unit;
2111 }
2095 dpt = devclass_get_device(dpt_devclass, unit);
2096 if (dpt == NULL)
2097 return (INVALID_UNIT);
2112
2098
2113 return (INVALID_UNIT);
2114
2115valid_unit:
2116
2099 mtx_lock(&dpt->lock);
2117 if (dpt->target_mode_enabled) {
2118 if ((channel >= dpt->channels) || (target > dpt->max_id) ||
2119 (lun > dpt->max_lun)) {
2100 if (dpt->target_mode_enabled) {
2101 if ((channel >= dpt->channels) || (target > dpt->max_id) ||
2102 (lun > dpt->max_lun)) {
2103 mtx_unlock(&dpt->lock);
2120 return (INVALID_SENDER);
2121 }
2122 if ((dpt->rw_buffer[channel][target][lun] == NULL) ||
2104 return (INVALID_SENDER);
2105 }
2106 if ((dpt->rw_buffer[channel][target][lun] == NULL) ||
2123 (dpt->buffer_receiver[channel][target][lun] == NULL))
2107 (dpt->buffer_receiver[channel][target][lun] == NULL)) {
2108 mtx_unlock(&dpt->lock);
2124 return (NOT_REGISTERED);
2109 return (NOT_REGISTERED);
2110 }
2125
2111
2126 ospl = splsoftcam();
2127 /* Process the free list */
2128 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2112 /* Process the free list */
2113 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2129 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
2130 " Please try later\n",
2131 dpt->unit);
2132 splx(ospl);
2114 device_printf(dpt->dev,
2115 "ERROR: Cannot allocate any more free CCB's.\n"
2116 " Please try later\n");
2117 mtx_unlock(&dpt->lock);
2133 return (NO_RESOURCES);
2134 }
2135 /* Now grab the newest CCB */
2136 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2118 return (NO_RESOURCES);
2119 }
2120 /* Now grab the newest CCB */
2121 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2137 splx(ospl);
2138 panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit);
2122 mtx_unlock(&dpt->lock);
2123 panic("%s: Got a NULL CCB from pop_free()\n",
2124 device_get_nameunit(dpt->dev));
2139 }
2125 }
2140 splx(ospl);
2141
2142 bcopy(dpt->rw_buffer[channel][target][lun] + offset, data, length);
2143 dpt_target_ccb(dpt, channel, target, lun, ccb, mode,
2144 SCSI_TM_WRITE_BUFFER,
2145 length, offset);
2146 ccb->std_callback = (ccb_callback) callback; /* Potential trouble */
2147
2126
2127 bcopy(dpt->rw_buffer[channel][target][lun] + offset, data, length);
2128 dpt_target_ccb(dpt, channel, target, lun, ccb, mode,
2129 SCSI_TM_WRITE_BUFFER,
2130 length, offset);
2131 ccb->std_callback = (ccb_callback) callback; /* Potential trouble */
2132
2148 ospl = splcam();
2149 ccb->transaction_id = ++dpt->commands_processed;
2150
2151#ifdef DPT_MEASURE_PERFORMANCE
2152 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++;
2153 ccb->command_started = microtime_now;
2154#endif
2155 dpt_Qadd_waiting(dpt, ccb);
2156 dpt_sched_queue(dpt);
2157
2133 ccb->transaction_id = ++dpt->commands_processed;
2134
2135#ifdef DPT_MEASURE_PERFORMANCE
2136 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++;
2137 ccb->command_started = microtime_now;
2138#endif
2139 dpt_Qadd_waiting(dpt, ccb);
2140 dpt_sched_queue(dpt);
2141
2158 splx(ospl);
2142 mtx_unlock(&dpt->lock);
2159 return (0);
2160 }
2143 return (0);
2144 }
2145 mtx_unlock(&dpt->lock);
2161 return (DRIVER_DOWN);
2162}
2163
2164static void
2165dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
2166{
2146 return (DRIVER_DOWN);
2147}
2148
2149static void
2150dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
2151{
2167 int ospl;
2168 eata_ccb_t *cp;
2169
2170 cp = &ccb->eata_ccb;
2171
2172 /*
2173 * Remove the CCB from the waiting queue.
2174 * We do NOT put it back on the free, etc., queues as it is a special
2175 * ccb, owned by the dpt_softc of this unit.
2176 */
2152 eata_ccb_t *cp;
2153
2154 cp = &ccb->eata_ccb;
2155
2156 /*
2157 * Remove the CCB from the waiting queue.
2158 * We do NOT put it back on the free, etc., queues as it is a special
2159 * ccb, owned by the dpt_softc of this unit.
2160 */
2177 ospl = splsoftcam();
2178 dpt_Qremove_completed(dpt, ccb);
2161 dpt_Qremove_completed(dpt, ccb);
2179 splx(ospl);
2180
2181#define br_channel (ccb->eata_ccb.cp_channel)
2182#define br_target (ccb->eata_ccb.cp_id)
2183#define br_lun (ccb->eata_ccb.cp_LUN)
2184#define br_index [br_channel][br_target][br_lun]
2185#define read_buffer_callback (dpt->buffer_receiver br_index )
2186#define read_buffer (dpt->rw_buffer[br_channel][br_target][br_lun])
2187#define cb(offset) (ccb->eata_ccb.cp_cdb[offset])
2188#define br_offset ((cb(3) << 16) | (cb(4) << 8) | cb(5))
2189#define br_length ((cb(6) << 16) | (cb(7) << 8) | cb(8))
2190
2191 /* Different reasons for being here, you know... */
2192 switch (ccb->eata_ccb.cp_scsi_cmd) {
2193 case SCSI_TM_READ_BUFFER:
2194 if (read_buffer_callback != NULL) {
2195 /* This is a buffer generated by a kernel process */
2162
2163#define br_channel (ccb->eata_ccb.cp_channel)
2164#define br_target (ccb->eata_ccb.cp_id)
2165#define br_lun (ccb->eata_ccb.cp_LUN)
2166#define br_index [br_channel][br_target][br_lun]
2167#define read_buffer_callback (dpt->buffer_receiver br_index )
2168#define read_buffer (dpt->rw_buffer[br_channel][br_target][br_lun])
2169#define cb(offset) (ccb->eata_ccb.cp_cdb[offset])
2170#define br_offset ((cb(3) << 16) | (cb(4) << 8) | cb(5))
2171#define br_length ((cb(6) << 16) | (cb(7) << 8) | cb(8))
2172
2173 /* Different reasons for being here, you know... */
2174 switch (ccb->eata_ccb.cp_scsi_cmd) {
2175 case SCSI_TM_READ_BUFFER:
2176 if (read_buffer_callback != NULL) {
2177 /* This is a buffer generated by a kernel process */
2196 read_buffer_callback(dpt->unit, br_channel,
2197 br_target, br_lun,
2178 read_buffer_callback(device_get_unit(dpt->dev),
2179 br_channel, br_target, br_lun,
2198 read_buffer,
2199 br_offset, br_length);
2200 } else {
2201 /*
2202 * This is a buffer waited for by a user (sleeping)
2203 * command
2204 */
2205 wakeup(ccb);
2206 }
2207
2208 /* We ALWAYS re-issue the same command; args are don't-care */
2209 dpt_set_target(1, 0, 0, 0, 0, 0, 0, 0, 0);
2210 break;
2211
2212 case SCSI_TM_WRITE_BUFFER:
2180 read_buffer,
2181 br_offset, br_length);
2182 } else {
2183 /*
2184 * This is a buffer waited for by a user (sleeping)
2185 * command
2186 */
2187 wakeup(ccb);
2188 }
2189
2190 /* We ALWAYS re-issue the same command; args are don't-care */
2191 dpt_set_target(1, 0, 0, 0, 0, 0, 0, 0, 0);
2192 break;
2193
2194 case SCSI_TM_WRITE_BUFFER:
2213 (ccb->wrbuff_callback) (dpt->unit, br_channel, br_target,
2214 br_offset, br_length,
2195 (ccb->wrbuff_callback) (device_get_unit(dpt->dev), br_channel,
2196 br_target, br_offset, br_length,
2215 br_lun, ccb->status_packet.hba_stat);
2216 break;
2217 default:
2197 br_lun, ccb->status_packet.hba_stat);
2198 break;
2199 default:
2218 printf("dpt%d: %s is an unsupported command for target mode\n",
2219 dpt->unit, scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd));
2200 device_printf(dpt->dev,
2201 "%s is an unsupported command for target mode\n",
2202 scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd));
2220 }
2203 }
2221 ospl = splsoftcam();
2222 dpt->target_ccb[br_channel][br_target][br_lun] = NULL;
2223 dpt_Qpush_free(dpt, ccb);
2204 dpt->target_ccb[br_channel][br_target][br_lun] = NULL;
2205 dpt_Qpush_free(dpt, ccb);
2224 splx(ospl);
2225}
2226
2227
2228/*
2229 * Use this function to register a client for a buffer read target operation.
2230 * The function you register will be called every time a buffer is received
2231 * by the target mode code.
2232 */
2233dpt_rb_t
2234dpt_register_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
2235 u_int8_t mode, u_int16_t length, u_int16_t offset,
2236 dpt_rec_buff callback, dpt_rb_op_t op)
2237{
2238 dpt_softc_t *dpt;
2239 dpt_ccb_t *ccb = NULL;
2240 int ospl;
2241
2206}
2207
2208
2209/*
2210 * Use this function to register a client for a buffer read target operation.
2211 * The function you register will be called every time a buffer is received
2212 * by the target mode code.
2213 */
2214dpt_rb_t
2215dpt_register_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun,
2216 u_int8_t mode, u_int16_t length, u_int16_t offset,
2217 dpt_rec_buff callback, dpt_rb_op_t op)
2218{
2219 dpt_softc_t *dpt;
2220 dpt_ccb_t *ccb = NULL;
2221 int ospl;
2222
2242 for (dpt = TAILQ_FIRST(&dpt_softc_list);
2243 dpt != NULL;
2244 dpt = TAILQ_NEXT(dpt, links)) {
2245 if (dpt->unit == unit)
2246 goto valid_unit;
2247 }
2223 dpt = devclass_get_device(dpt_devclass, unit);
2224 if (dpt == NULL)
2225 return (INVALID_UNIT);
2226 mtx_lock(&dpt->lock);
2248
2227
2249 return (INVALID_UNIT);
2250
2251valid_unit:
2252
2253 if (dpt->state & DPT_HA_SHUTDOWN_ACTIVE)
2228 if (dpt->state & DPT_HA_SHUTDOWN_ACTIVE) {
2229 mtx_unlock(&dpt->lock);
2254 return (DRIVER_DOWN);
2230 return (DRIVER_DOWN);
2231 }
2255
2256 if ((channel > (dpt->channels - 1)) || (target > (dpt->max_id - 1)) ||
2232
2233 if ((channel > (dpt->channels - 1)) || (target > (dpt->max_id - 1)) ||
2257 (lun > (dpt->max_lun - 1)))
2234 (lun > (dpt->max_lun - 1))) {
2235 mtx_unlock(&dpt->lock);
2258 return (INVALID_SENDER);
2236 return (INVALID_SENDER);
2237 }
2259
2260 if (dpt->buffer_receiver[channel][target][lun] == NULL) {
2261 if (op == REGISTER_BUFFER) {
2262 /* Assign the requested callback */
2263 dpt->buffer_receiver[channel][target][lun] = callback;
2264 /* Get a CCB */
2238
2239 if (dpt->buffer_receiver[channel][target][lun] == NULL) {
2240 if (op == REGISTER_BUFFER) {
2241 /* Assign the requested callback */
2242 dpt->buffer_receiver[channel][target][lun] = callback;
2243 /* Get a CCB */
2265 ospl = splsoftcam();
2266
2267 /* Process the free list */
2268 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2244
2245 /* Process the free list */
2246 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2269 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
2270 " Please try later\n",
2271 dpt->unit);
2272 splx(ospl);
2247 device_printf(dpt->dev,
2248 "ERROR: Cannot allocate any more free CCB's.\n"
2249 " Please try later\n");
2250 mtx_unlock(&dpt->lock);
2273 return (NO_RESOURCES);
2274 }
2275 /* Now grab the newest CCB */
2276 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2251 return (NO_RESOURCES);
2252 }
2253 /* Now grab the newest CCB */
2254 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2277 splx(ospl);
2278 panic("dpt%d: Got a NULL CCB from pop_free()\n",
2279 dpt->unit);
2255 mtx_unlock(&dpt->lock);
2256 panic("%s: Got a NULL CCB from pop_free()\n",
2257 device_get_nameunit(dpt->dev));
2280 }
2258 }
2281 splx(ospl);
2282
2283 /* Clean up the leftover of the previous tenant */
2284 ccb->status = DPT_CCB_STATE_NEW;
2285 dpt->target_ccb[channel][target][lun] = ccb;
2286
2287 dpt->rw_buffer[channel][target][lun] =
2288 malloc(DPT_RW_BUFFER_SIZE, M_DEVBUF, M_NOWAIT);
2289 if (dpt->rw_buffer[channel][target][lun] == NULL) {
2259
2260 /* Clean up the leftover of the previous tenant */
2261 ccb->status = DPT_CCB_STATE_NEW;
2262 dpt->target_ccb[channel][target][lun] = ccb;
2263
2264 dpt->rw_buffer[channel][target][lun] =
2265 malloc(DPT_RW_BUFFER_SIZE, M_DEVBUF, M_NOWAIT);
2266 if (dpt->rw_buffer[channel][target][lun] == NULL) {
2290 printf("dpt%d: Failed to allocate "
2291 "Target-Mode buffer\n", dpt->unit);
2292 ospl = splsoftcam();
2267 device_printf(dpt->dev, "Failed to allocate "
2268 "Target-Mode buffer\n");
2293 dpt_Qpush_free(dpt, ccb);
2269 dpt_Qpush_free(dpt, ccb);
2294 splx(ospl);
2270 mtx_unlock(&dpt->lock);
2295 return (NO_RESOURCES);
2296 }
2297 dpt_set_target(0, dpt, channel, target, lun, mode,
2298 length, offset, ccb);
2271 return (NO_RESOURCES);
2272 }
2273 dpt_set_target(0, dpt, channel, target, lun, mode,
2274 length, offset, ccb);
2275 mtx_unlock(&dpt->lock);
2299 return (SUCCESSFULLY_REGISTERED);
2276 return (SUCCESSFULLY_REGISTERED);
2300 } else
2277 } else {
2278 mtx_unlock(&dpt->lock);
2301 return (NOT_REGISTERED);
2279 return (NOT_REGISTERED);
2280 }
2302 } else {
2303 if (op == REGISTER_BUFFER) {
2281 } else {
2282 if (op == REGISTER_BUFFER) {
2304 if (dpt->buffer_receiver[channel][target][lun] == callback)
2283 if (dpt->buffer_receiver[channel][target][lun] == callback) {
2284 mtx_unlock(&dpt->lock);
2305 return (ALREADY_REGISTERED);
2285 return (ALREADY_REGISTERED);
2306 else
2286 } else {
2287 mtx_unlock(&dpt->lock);
2307 return (REGISTERED_TO_ANOTHER);
2288 return (REGISTERED_TO_ANOTHER);
2289 }
2308 } else {
2309 if (dpt->buffer_receiver[channel][target][lun] == callback) {
2310 dpt->buffer_receiver[channel][target][lun] = NULL;
2290 } else {
2291 if (dpt->buffer_receiver[channel][target][lun] == callback) {
2292 dpt->buffer_receiver[channel][target][lun] = NULL;
2311 ospl = splsoftcam();
2312 dpt_Qpush_free(dpt, ccb);
2293 dpt_Qpush_free(dpt, ccb);
2313 splx(ospl);
2314 free(dpt->rw_buffer[channel][target][lun], M_DEVBUF);
2294 free(dpt->rw_buffer[channel][target][lun], M_DEVBUF);
2295 mtx_unlock(&dpt->lock);
2315 return (SUCCESSFULLY_REGISTERED);
2296 return (SUCCESSFULLY_REGISTERED);
2316 } else
2297 } else {
2298 mtx_unlock(&dpt->lock);
2317 return (INVALID_CALLBACK);
2299 return (INVALID_CALLBACK);
2300 }
2318 }
2319
2320 }
2301 }
2302
2303 }
2304 mtx_unlock(&dpt->lock);
2321}
2322
2323/* Return the state of the blinking DPT LED's */
2324u_int8_t
2325dpt_blinking_led(dpt_softc_t * dpt)
2326{
2327 int ndx;
2305}
2306
2307/* Return the state of the blinking DPT LED's */
2308u_int8_t
2309dpt_blinking_led(dpt_softc_t * dpt)
2310{
2311 int ndx;
2328 int ospl;
2329 u_int32_t state;
2330 u_int32_t previous;
2331 u_int8_t result;
2332
2312 u_int32_t state;
2313 u_int32_t previous;
2314 u_int8_t result;
2315
2333 ospl = splcam();
2334
2316 mtx_assert(&dpt->lock, MA_OWNED);
2335 result = 0;
2336
2337 for (ndx = 0, state = 0, previous = 0;
2338 (ndx < 10) && (state != previous);
2339 ndx++) {
2340 previous = state;
2341 state = dpt_inl(dpt, 1);
2342 }
2343
2344 if ((state == previous) && (state == DPT_BLINK_INDICATOR))
2345 result = dpt_inb(dpt, 5);
2346
2317 result = 0;
2318
2319 for (ndx = 0, state = 0, previous = 0;
2320 (ndx < 10) && (state != previous);
2321 ndx++) {
2322 previous = state;
2323 state = dpt_inl(dpt, 1);
2324 }
2325
2326 if ((state == previous) && (state == DPT_BLINK_INDICATOR))
2327 result = dpt_inb(dpt, 5);
2328
2347 splx(ospl);
2348 return (result);
2349}
2350
2351/*
2352 * Execute a command which did not come from the kernel's SCSI layer.
2353 * The only way to map user commands to bus and target is to comply with the
2354 * standard DPT wire-down scheme:
2355 */
2356int
2357dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
2358 caddr_t cmdarg, int minor_no)
2359{
2360 dpt_ccb_t *ccb;
2361 void *data;
2362 int channel, target, lun;
2363 int huh;
2364 int result;
2329 return (result);
2330}
2331
2332/*
2333 * Execute a command which did not come from the kernel's SCSI layer.
2334 * The only way to map user commands to bus and target is to comply with the
2335 * standard DPT wire-down scheme:
2336 */
2337int
2338dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd,
2339 caddr_t cmdarg, int minor_no)
2340{
2341 dpt_ccb_t *ccb;
2342 void *data;
2343 int channel, target, lun;
2344 int huh;
2345 int result;
2365 int ospl;
2366 int submitted;
2367
2346 int submitted;
2347
2348 mtx_assert(&dpt->lock, MA_OWNED);
2368 data = NULL;
2369 channel = minor2hba(minor_no);
2370 target = minor2target(minor_no);
2371 lun = minor2lun(minor_no);
2372
2373 if ((channel > (dpt->channels - 1))
2374 || (target > dpt->max_id)
2375 || (lun > dpt->max_lun))

--- 4 unchanged lines hidden (view full) ---

2380 if ((user_cmd->eataID[0] != 'E')
2381 || (user_cmd->eataID[1] != 'A')
2382 || (user_cmd->eataID[2] != 'T')
2383 || (user_cmd->eataID[3] != 'A')) {
2384 return (ENXIO);
2385 }
2386 }
2387 /* Get a DPT CCB, so we can prepare a command */
2349 data = NULL;
2350 channel = minor2hba(minor_no);
2351 target = minor2target(minor_no);
2352 lun = minor2lun(minor_no);
2353
2354 if ((channel > (dpt->channels - 1))
2355 || (target > dpt->max_id)
2356 || (lun > dpt->max_lun))

--- 4 unchanged lines hidden (view full) ---

2361 if ((user_cmd->eataID[0] != 'E')
2362 || (user_cmd->eataID[1] != 'A')
2363 || (user_cmd->eataID[2] != 'T')
2364 || (user_cmd->eataID[3] != 'A')) {
2365 return (ENXIO);
2366 }
2367 }
2368 /* Get a DPT CCB, so we can prepare a command */
2388 ospl = splsoftcam();
2389
2390 /* Process the free list */
2391 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2369
2370 /* Process the free list */
2371 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) {
2392 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n"
2393 " Please try later\n",
2394 dpt->unit);
2395 splx(ospl);
2372 device_printf(dpt->dev,
2373 "ERROR: Cannot allocate any more free CCB's.\n"
2374 " Please try later\n");
2396 return (EFAULT);
2397 }
2398 /* Now grab the newest CCB */
2399 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2375 return (EFAULT);
2376 }
2377 /* Now grab the newest CCB */
2378 if ((ccb = dpt_Qpop_free(dpt)) == NULL) {
2400 splx(ospl);
2401 panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit);
2379 panic("%s: Got a NULL CCB from pop_free()\n",
2380 device_get_nameunit(dpt->dev));
2402 } else {
2381 } else {
2403 splx(ospl);
2404 /* Clean up the leftover of the previous tenant */
2405 ccb->status = DPT_CCB_STATE_NEW;
2406 }
2407
2408 bcopy((caddr_t) & user_cmd->command_packet, (caddr_t) & ccb->eata_ccb,
2409 sizeof(eata_ccb_t));
2410
2411 /* We do not want to do user specified scatter/gather. Why?? */

--- 16 unchanged lines hidden (view full) ---

2428 ccb->eata_ccb.cp_datalen,
2429 0x10000);
2430 } else {
2431 data = malloc(ccb->eata_ccb.cp_datalen, M_TEMP,
2432 M_WAITOK);
2433 }
2434
2435 if (data == NULL) {
2382 /* Clean up the leftover of the previous tenant */
2383 ccb->status = DPT_CCB_STATE_NEW;
2384 }
2385
2386 bcopy((caddr_t) & user_cmd->command_packet, (caddr_t) & ccb->eata_ccb,
2387 sizeof(eata_ccb_t));
2388
2389 /* We do not want to do user specified scatter/gather. Why?? */

--- 16 unchanged lines hidden (view full) ---

2406 ccb->eata_ccb.cp_datalen,
2407 0x10000);
2408 } else {
2409 data = malloc(ccb->eata_ccb.cp_datalen, M_TEMP,
2410 M_WAITOK);
2411 }
2412
2413 if (data == NULL) {
2436 printf("dpt%d: Cannot allocate %d bytes "
2437 "for EATA command\n", dpt->unit,
2414 device_printf(dpt->dev, "Cannot allocate %d bytes "
2415 "for EATA command\n",
2438 ccb->eata_ccb.cp_datalen);
2439 return (EFAULT);
2440 }
2441#define usr_cmd_DMA (caddr_t)user_cmd->command_packet.cp_dataDMA
2442 if (ccb->eata_ccb.DataIn == 1) {
2443 if (copyin(usr_cmd_DMA,
2444 data, ccb->eata_ccb.cp_datalen) == -1)
2445 return (EFAULT);

--- 19 unchanged lines hidden (view full) ---

2465 * We are required to quiet a SCSI bus.
2466 * since we do not queue comands on a bus basis,
2467 * we wait for ALL commands on a controller to complete.
2468 * In the mean time, sched_queue() will not schedule new commands.
2469 */
2470 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
2471 && (ccb->eata_ccb.cp_cdb[2] == BUS_QUIET)) {
2472 /* We wait for ALL traffic for this HBa to subside */
2416 ccb->eata_ccb.cp_datalen);
2417 return (EFAULT);
2418 }
2419#define usr_cmd_DMA (caddr_t)user_cmd->command_packet.cp_dataDMA
2420 if (ccb->eata_ccb.DataIn == 1) {
2421 if (copyin(usr_cmd_DMA,
2422 data, ccb->eata_ccb.cp_datalen) == -1)
2423 return (EFAULT);

--- 19 unchanged lines hidden (view full) ---

2443 * We are required to quiet a SCSI bus.
2444 * since we do not queue comands on a bus basis,
2445 * we wait for ALL commands on a controller to complete.
2446 * In the mean time, sched_queue() will not schedule new commands.
2447 */
2448 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
2449 && (ccb->eata_ccb.cp_cdb[2] == BUS_QUIET)) {
2450 /* We wait for ALL traffic for this HBa to subside */
2473 ospl = splsoftcam();
2474 dpt->state |= DPT_HA_QUIET;
2451 dpt->state |= DPT_HA_QUIET;
2475 splx(ospl);
2476
2477 while ((submitted = dpt->submitted_ccbs_count) != 0) {
2452
2453 while ((submitted = dpt->submitted_ccbs_count) != 0) {
2478 huh = tsleep((void *) dpt, PCATCH | PRIBIO, "dptqt",
2479 100 * hz);
2454 huh = mtx_sleep((void *) dpt, &dpt->lock,
2455 PCATCH | PRIBIO, "dptqt", 100 * hz);
2480 switch (huh) {
2481 case 0:
2482 /* Wakeup call received */
2483 break;
2484 case EWOULDBLOCK:
2485 /* Timer Expired */
2486 break;
2487 default:
2488 /* anything else */
2489 break;
2490 }
2491 }
2492 }
2493 /* Resume normal operation */
2494 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
2495 && (ccb->eata_ccb.cp_cdb[2] == BUS_UNQUIET)) {
2456 switch (huh) {
2457 case 0:
2458 /* Wakeup call received */
2459 break;
2460 case EWOULDBLOCK:
2461 /* Timer Expired */
2462 break;
2463 default:
2464 /* anything else */
2465 break;
2466 }
2467 }
2468 }
2469 /* Resume normal operation */
2470 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD)
2471 && (ccb->eata_ccb.cp_cdb[2] == BUS_UNQUIET)) {
2496 ospl = splsoftcam();
2497 dpt->state &= ~DPT_HA_QUIET;
2472 dpt->state &= ~DPT_HA_QUIET;
2498 splx(ospl);
2499 }
2500 /**
2501 * Schedule the command and submit it.
2502 * We bypass dpt_sched_queue, as it will block on DPT_HA_QUIET
2503 */
2504 ccb->xs = NULL;
2505 ccb->flags = 0;
2506 ccb->eata_ccb.Auto_Req_Sen = 1; /* We always want this feature */
2507
2508 ccb->transaction_id = ++dpt->commands_processed;
2509 ccb->std_callback = (ccb_callback) dpt_user_cmd_done;
2510 ccb->result = (u_int32_t) & cmdarg;
2511 ccb->data = data;
2512
2513#ifdef DPT_MEASURE_PERFORMANCE
2514 ++dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd];
2515 ccb->command_started = microtime_now;
2516#endif
2473 }
2474 /**
2475 * Schedule the command and submit it.
2476 * We bypass dpt_sched_queue, as it will block on DPT_HA_QUIET
2477 */
2478 ccb->xs = NULL;
2479 ccb->flags = 0;
2480 ccb->eata_ccb.Auto_Req_Sen = 1; /* We always want this feature */
2481
2482 ccb->transaction_id = ++dpt->commands_processed;
2483 ccb->std_callback = (ccb_callback) dpt_user_cmd_done;
2484 ccb->result = (u_int32_t) & cmdarg;
2485 ccb->data = data;
2486
2487#ifdef DPT_MEASURE_PERFORMANCE
2488 ++dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd];
2489 ccb->command_started = microtime_now;
2490#endif
2517 ospl = splcam();
2518 dpt_Qadd_waiting(dpt, ccb);
2491 dpt_Qadd_waiting(dpt, ccb);
2519 splx(ospl);
2520
2521 dpt_sched_queue(dpt);
2522
2523 /* Wait for the command to complete */
2492
2493 dpt_sched_queue(dpt);
2494
2495 /* Wait for the command to complete */
2524 (void) tsleep((void *) ccb, PCATCH | PRIBIO, "dptucw", 100 * hz);
2496 (void) mtx_sleep((void *) ccb, &dpt->lock, PCATCH | PRIBIO, "dptucw",
2497 100 * hz);
2525
2526 /* Free allocated memory */
2527 if (data != NULL)
2528 free(data, M_TEMP);
2529
2530 return (0);
2531}
2532
2533static void
2534dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
2535{
2498
2499 /* Free allocated memory */
2500 if (data != NULL)
2501 free(data, M_TEMP);
2502
2503 return (0);
2504}
2505
2506static void
2507dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb)
2508{
2536 int ospl = splsoftcam();
2537 u_int32_t result;
2538 caddr_t cmd_arg;
2539
2509 u_int32_t result;
2510 caddr_t cmd_arg;
2511
2512 mtx_unlock(&dpt->lock);
2513
2540 /**
2541 * If Auto Request Sense is on, copyout the sense struct
2542 */
2543#define usr_pckt_DMA (caddr_t)(intptr_t)ntohl(ccb->eata_ccb.cp_reqDMA)
2544#define usr_pckt_len ntohl(ccb->eata_ccb.cp_datalen)
2545 if (ccb->eata_ccb.Auto_Req_Sen == 1) {
2546 if (copyout((caddr_t) & ccb->sense_data, usr_pckt_DMA,
2547 sizeof(struct scsi_sense_data))) {
2514 /**
2515 * If Auto Request Sense is on, copyout the sense struct
2516 */
2517#define usr_pckt_DMA (caddr_t)(intptr_t)ntohl(ccb->eata_ccb.cp_reqDMA)
2518#define usr_pckt_len ntohl(ccb->eata_ccb.cp_datalen)
2519 if (ccb->eata_ccb.Auto_Req_Sen == 1) {
2520 if (copyout((caddr_t) & ccb->sense_data, usr_pckt_DMA,
2521 sizeof(struct scsi_sense_data))) {
2522 mtx_lock(&dpt->lock);
2548 ccb->result = EFAULT;
2549 dpt_Qpush_free(dpt, ccb);
2523 ccb->result = EFAULT;
2524 dpt_Qpush_free(dpt, ccb);
2550 splx(ospl);
2551 wakeup(ccb);
2552 return;
2553 }
2554 }
2555 /* If DataIn is on, copyout the data */
2556 if ((ccb->eata_ccb.DataIn == 1)
2557 && (ccb->status_packet.hba_stat == HA_NO_ERROR)) {
2558 if (copyout(ccb->data, usr_pckt_DMA, usr_pckt_len)) {
2525 wakeup(ccb);
2526 return;
2527 }
2528 }
2529 /* If DataIn is on, copyout the data */
2530 if ((ccb->eata_ccb.DataIn == 1)
2531 && (ccb->status_packet.hba_stat == HA_NO_ERROR)) {
2532 if (copyout(ccb->data, usr_pckt_DMA, usr_pckt_len)) {
2533 mtx_lock(&dpt->lock);
2559 dpt_Qpush_free(dpt, ccb);
2560 ccb->result = EFAULT;
2561
2534 dpt_Qpush_free(dpt, ccb);
2535 ccb->result = EFAULT;
2536
2562 splx(ospl);
2563 wakeup(ccb);
2564 return;
2565 }
2566 }
2567 /* Copyout the status */
2568 result = ccb->status_packet.hba_stat;
2569 cmd_arg = (caddr_t) ccb->result;
2570
2571 if (copyout((caddr_t) & result, cmd_arg, sizeof(result))) {
2537 wakeup(ccb);
2538 return;
2539 }
2540 }
2541 /* Copyout the status */
2542 result = ccb->status_packet.hba_stat;
2543 cmd_arg = (caddr_t) ccb->result;
2544
2545 if (copyout((caddr_t) & result, cmd_arg, sizeof(result))) {
2546 mtx_lock(&dpt->lock);
2572 dpt_Qpush_free(dpt, ccb);
2573 ccb->result = EFAULT;
2547 dpt_Qpush_free(dpt, ccb);
2548 ccb->result = EFAULT;
2574 splx(ospl);
2575 wakeup(ccb);
2576 return;
2577 }
2549 wakeup(ccb);
2550 return;
2551 }
2552 mtx_lock(&dpt->lock);
2578 /* Put the CCB back in the freelist */
2579 ccb->state |= DPT_CCB_STATE_COMPLETED;
2580 dpt_Qpush_free(dpt, ccb);
2581
2582 /* Free allocated memory */
2553 /* Put the CCB back in the freelist */
2554 ccb->state |= DPT_CCB_STATE_COMPLETED;
2555 dpt_Qpush_free(dpt, ccb);
2556
2557 /* Free allocated memory */
2583 splx(ospl);
2584 return;
2585}
2586
2587#ifdef DPT_HANDLE_TIMEOUTS
2588/**
2589 * This function walks down the SUBMITTED queue.
2590 * Every request that is too old gets aborted and marked.
2591 * Since the DPT will complete (interrupt) immediately (what does that mean?),

--- 13 unchanged lines hidden (view full) ---

2605 * every ten seconds for few microseconds and, on systems with healthy
2606 * hardware, does not do anything anyway.
2607 */
2608
2609static void
2610dpt_handle_timeouts(dpt_softc_t * dpt)
2611{
2612 dpt_ccb_t *ccb;
2558 return;
2559}
2560
2561#ifdef DPT_HANDLE_TIMEOUTS
2562/**
2563 * This function walks down the SUBMITTED queue.
2564 * Every request that is too old gets aborted and marked.
2565 * Since the DPT will complete (interrupt) immediately (what does that mean?),

--- 13 unchanged lines hidden (view full) ---

2579 * every ten seconds for few microseconds and, on systems with healthy
2580 * hardware, does not do anything anyway.
2581 */
2582
2583static void
2584dpt_handle_timeouts(dpt_softc_t * dpt)
2585{
2586 dpt_ccb_t *ccb;
2613 int ospl;
2614
2587
2615 ospl = splcam();
2616
2617 if (dpt->state & DPT_HA_TIMEOUTS_ACTIVE) {
2588 if (dpt->state & DPT_HA_TIMEOUTS_ACTIVE) {
2618 printf("dpt%d WARNING: Timeout Handling Collision\n",
2619 dpt->unit);
2620 splx(ospl);
2589 device_printf(dpt->dev, "WARNING: Timeout Handling Collision\n");
2621 return;
2622 }
2623 dpt->state |= DPT_HA_TIMEOUTS_ACTIVE;
2624
2625 /* Loop through the entire submitted queue, looking for lost souls */
2590 return;
2591 }
2592 dpt->state |= DPT_HA_TIMEOUTS_ACTIVE;
2593
2594 /* Loop through the entire submitted queue, looking for lost souls */
2626 for (ccb = TAILQ_FIRST(&dpt->submitted_ccbs);
2627 ccb != NULL;
2628 ccb = TAILQ_NEXT(ccb, links)) {
2595 TAILQ_FIRST(ccb, &&dpt->submitted_ccbs, links) {
2629 struct scsi_xfer *xs;
2630 u_int32_t age, max_age;
2631
2632 xs = ccb->xs;
2633 age = dpt_time_delta(ccb->command_started, microtime_now);
2634
2635#define TenSec 10000000
2636

--- 15 unchanged lines hidden (view full) ---

2652 if (ccb->state & DPT_CCB_STATE_MARKED_LOST) {
2653 /* Remember who is next */
2654 if (age > (max_age * 2)) {
2655 dpt_Qremove_submitted(dpt, ccb);
2656 ccb->state &= ~DPT_CCB_STATE_MARKED_LOST;
2657 ccb->state |= DPT_CCB_STATE_ABORTED;
2658#define cmd_name scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd)
2659 if (ccb->retries++ > DPT_RETRIES) {
2596 struct scsi_xfer *xs;
2597 u_int32_t age, max_age;
2598
2599 xs = ccb->xs;
2600 age = dpt_time_delta(ccb->command_started, microtime_now);
2601
2602#define TenSec 10000000
2603

--- 15 unchanged lines hidden (view full) ---

2619 if (ccb->state & DPT_CCB_STATE_MARKED_LOST) {
2620 /* Remember who is next */
2621 if (age > (max_age * 2)) {
2622 dpt_Qremove_submitted(dpt, ccb);
2623 ccb->state &= ~DPT_CCB_STATE_MARKED_LOST;
2624 ccb->state |= DPT_CCB_STATE_ABORTED;
2625#define cmd_name scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd)
2626 if (ccb->retries++ > DPT_RETRIES) {
2660 printf("dpt%d ERROR: Destroying stale "
2627 device_printf(dpt->dev,
2628 "ERROR: Destroying stale "
2661 "%d (%s)\n"
2662 " on "
2663 "c%db%dt%du%d (%d/%d)\n",
2629 "%d (%s)\n"
2630 " on "
2631 "c%db%dt%du%d (%d/%d)\n",
2664 dpt->unit, ccb->transaction_id,
2632 ccb->transaction_id,
2665 cmd_name,
2633 cmd_name,
2666 dpt->unit,
2634 device_get_unit(dpt->dev),
2667 ccb->eata_ccb.cp_channel,
2668 ccb->eata_ccb.cp_id,
2669 ccb->eata_ccb.cp_LUN, age,
2670 ccb->retries);
2671#define send_ccb &ccb->eata_ccb
2672#define ESA EATA_SPECIFIC_ABORT
2673 (void) dpt_send_immediate(dpt,
2674 send_ccb,
2675 ESA,
2676 0, 0);
2677 dpt_Qpush_free(dpt, ccb);
2678
2679 /* The SCSI layer should re-try */
2680 xs->error |= XS_TIMEOUT;
2681 xs->flags |= SCSI_ITSDONE;
2682 scsi_done(xs);
2683 } else {
2635 ccb->eata_ccb.cp_channel,
2636 ccb->eata_ccb.cp_id,
2637 ccb->eata_ccb.cp_LUN, age,
2638 ccb->retries);
2639#define send_ccb &ccb->eata_ccb
2640#define ESA EATA_SPECIFIC_ABORT
2641 (void) dpt_send_immediate(dpt,
2642 send_ccb,
2643 ESA,
2644 0, 0);
2645 dpt_Qpush_free(dpt, ccb);
2646
2647 /* The SCSI layer should re-try */
2648 xs->error |= XS_TIMEOUT;
2649 xs->flags |= SCSI_ITSDONE;
2650 scsi_done(xs);
2651 } else {
2684 printf("dpt%d ERROR: Stale %d (%s) on "
2652 device_printf(dpt->dev,
2653 "ERROR: Stale %d (%s) on "
2685 "c%db%dt%du%d (%d)\n"
2686 " gets another "
2687 "chance(%d/%d)\n",
2654 "c%db%dt%du%d (%d)\n"
2655 " gets another "
2656 "chance(%d/%d)\n",
2688 dpt->unit, ccb->transaction_id,
2657 ccb->transaction_id,
2689 cmd_name,
2658 cmd_name,
2690 dpt->unit,
2659 device_get_unit(dpt->dev),
2691 ccb->eata_ccb.cp_channel,
2692 ccb->eata_ccb.cp_id,
2693 ccb->eata_ccb.cp_LUN,
2694 age, ccb->retries, DPT_RETRIES);
2695
2696 dpt_Qpush_waiting(dpt, ccb);
2697 dpt_sched_queue(dpt);
2698 }
2699 }
2700 } else {
2701 /*
2702 * This is a transaction that is not to be destroyed
2703 * (yet) But it is too old for our liking. We wait as
2704 * long as the upper layer thinks. Not really, we
2705 * multiply that by the number of commands in the
2706 * submitted queue + 1.
2707 */
2708 if (!(ccb->state & DPT_CCB_STATE_MARKED_LOST) &&
2709 (age != ~0) && (age > max_age)) {
2660 ccb->eata_ccb.cp_channel,
2661 ccb->eata_ccb.cp_id,
2662 ccb->eata_ccb.cp_LUN,
2663 age, ccb->retries, DPT_RETRIES);
2664
2665 dpt_Qpush_waiting(dpt, ccb);
2666 dpt_sched_queue(dpt);
2667 }
2668 }
2669 } else {
2670 /*
2671 * This is a transaction that is not to be destroyed
2672 * (yet) But it is too old for our liking. We wait as
2673 * long as the upper layer thinks. Not really, we
2674 * multiply that by the number of commands in the
2675 * submitted queue + 1.
2676 */
2677 if (!(ccb->state & DPT_CCB_STATE_MARKED_LOST) &&
2678 (age != ~0) && (age > max_age)) {
2710 printf("dpt%d ERROR: Marking %d (%s) on "
2679 device_printf(dpt->dev,
2680 "ERROR: Marking %d (%s) on "
2711 "c%db%dt%du%d \n"
2712 " as late after %dusec\n",
2681 "c%db%dt%du%d \n"
2682 " as late after %dusec\n",
2713 dpt->unit, ccb->transaction_id,
2683 ccb->transaction_id,
2714 cmd_name,
2684 cmd_name,
2715 dpt->unit, ccb->eata_ccb.cp_channel,
2685 device_get_unit(dpt->dev),
2686 ccb->eata_ccb.cp_channel,
2716 ccb->eata_ccb.cp_id,
2717 ccb->eata_ccb.cp_LUN, age);
2718 ccb->state |= DPT_CCB_STATE_MARKED_LOST;
2719 }
2720 }
2721 }
2722
2723 dpt->state &= ~DPT_HA_TIMEOUTS_ACTIVE;
2687 ccb->eata_ccb.cp_id,
2688 ccb->eata_ccb.cp_LUN, age);
2689 ccb->state |= DPT_CCB_STATE_MARKED_LOST;
2690 }
2691 }
2692 }
2693
2694 dpt->state &= ~DPT_HA_TIMEOUTS_ACTIVE;
2724 splx(ospl);
2725}
2726
2727static void
2728dpt_timeout(void *arg)
2729{
2730 dpt_softc_t *dpt = (dpt_softc_t *) arg;
2731
2695}
2696
2697static void
2698dpt_timeout(void *arg)
2699{
2700 dpt_softc_t *dpt = (dpt_softc_t *) arg;
2701
2702 mtx_assert(&dpt->lock, MA_OWNED);
2732 if (!(dpt->state & DPT_HA_TIMEOUTS_ACTIVE))
2733 dpt_handle_timeouts(dpt);
2734
2703 if (!(dpt->state & DPT_HA_TIMEOUTS_ACTIVE))
2704 dpt_handle_timeouts(dpt);
2705
2735 timeout(dpt_timeout, (caddr_t) dpt, hz * 10);
2706 callout_reset(&dpt->timer, hz * 10, dpt_timeout, dpt);
2736}
2737
2738#endif /* DPT_HANDLE_TIMEOUTS */
2739
2740#endif
2707}
2708
2709#endif /* DPT_HANDLE_TIMEOUTS */
2710
2711#endif