2 * Copyright (c) 2001,2002 Thomas Quinot <thomas@cuivre.fr.eu.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.10.2.3 2003/05/21 09:24:55 thomas Exp $
29 * $DragonFly: src/sys/dev/disk/ata/atapi-cam.c,v 1.15 2008/05/18 20:30:22 pavalos Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
35 #include <sys/devicestat.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
39 #include <sys/thread2.h>
41 #include <bus/cam/cam.h>
42 #include <bus/cam/cam_ccb.h>
43 #include <bus/cam/cam_periph.h>
44 #include <bus/cam/cam_sim.h>
45 #include <bus/cam/cam_xpt_sim.h>
46 #include <bus/cam/cam_debug.h>
47 #include <bus/cam/scsi/scsi_all.h>
50 #include "atapi-all.h"
52 /* hardware command descriptor block */
54 struct atapi_xpt_softc
*softc
;
60 u_int8_t cmd
[CAM_MAX_CDBLEN
];
62 #define DOING_AUTOSENSE 1
65 TAILQ_ENTRY(atapi_hcb
) chain
;
68 /* private data associated with an ATA bus */
69 struct atapi_xpt_softc
{
70 struct ata_channel
*ata_ch
;
71 struct cam_path
*path
;
74 #define BUS_REGISTERED 0x01
75 #define RESOURCE_SHORTAGE 0x02
77 TAILQ_HEAD(,atapi_hcb
) pending_hcbs
;
78 LIST_ENTRY(atapi_xpt_softc
) chain
;
81 enum reinit_reason
{ ATTACH
, RESET
};
83 static LIST_HEAD(,atapi_xpt_softc
) all_buses
= LIST_HEAD_INITIALIZER(all_buses
);
86 static void atapi_action(struct cam_sim
*, union ccb
*);
87 static void atapi_poll(struct cam_sim
*);
88 static void atapi_async(void *, u_int32_t
, struct cam_path
*, void *);
89 static void atapi_async1(void *, u_int32_t
, struct cam_path
*, void *);
90 static int atapi_cb(struct atapi_request
*);
92 /* internal functions */
93 static void reinit_bus(struct atapi_xpt_softc
*scp
, enum reinit_reason reason
);
94 static void setup_dev(struct atapi_xpt_softc
*, struct ata_device
*);
95 static void setup_async_cb(struct atapi_xpt_softc
*, uint32_t);
96 static void cam_rescan_callback(struct cam_periph
*, union ccb
*);
97 static void cam_rescan(struct cam_sim
*);
98 static void free_hcb_and_ccb_done(struct atapi_hcb
*, u_int32_t
);
99 static struct atapi_hcb
*allocate_hcb(struct atapi_xpt_softc
*, int, int, union ccb
*);
100 static void free_hcb(struct atapi_hcb
*hcb
);
101 static void free_softc(struct atapi_xpt_softc
*scp
);
102 static struct atapi_xpt_softc
*get_softc(struct ata_channel
*ata_ch
);
103 static struct ata_device
*get_ata_device(struct atapi_xpt_softc
*scp
, int id
);
105 static MALLOC_DEFINE(M_ATACAM
, "ATA CAM transport", "ATA driver CAM-XPT layer");
108 atapi_cam_attach_bus(struct ata_channel
*ata_ch
)
110 struct atapi_xpt_softc
*scp
= NULL
;
111 struct cam_devq
*devq
= NULL
;
112 struct cam_sim
*sim
= NULL
;
113 struct cam_path
*path
= NULL
;
116 LIST_FOREACH(scp
, &all_buses
, chain
) {
117 if (scp
->ata_ch
== ata_ch
)
121 scp
= kmalloc(sizeof(struct atapi_xpt_softc
), M_ATACAM
, M_INTWAIT
| M_ZERO
);
122 scp
->ata_ch
= ata_ch
;
123 TAILQ_INIT(&scp
->pending_hcbs
);
124 LIST_INSERT_HEAD(&all_buses
, scp
, chain
);
125 unit
= device_get_unit(ata_ch
->dev
);
127 devq
= cam_simq_alloc(16);
128 sim
= cam_sim_alloc(atapi_action
, atapi_poll
, "ata", (void *)scp
,
129 unit
, &sim_mplock
, 1, 1, devq
);
130 cam_simq_release(devq
);
135 if (xpt_bus_register(sim
, 0) != CAM_SUCCESS
) {
138 scp
->flags
|= BUS_REGISTERED
;
140 if (xpt_create_path(&path
, /*periph*/ NULL
,
141 cam_sim_path(sim
), CAM_TARGET_WILDCARD
,
142 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
147 CAM_DEBUG(path
, CAM_DEBUG_TRACE
, ("Registered SIM for ata%d\n", unit
));
149 setup_async_cb(scp
, AC_LOST_DEVICE
);
150 reinit_bus(scp
, ATTACH
);
158 atapi_cam_detach_bus(struct ata_channel
*ata_ch
)
160 struct atapi_xpt_softc
*scp
= get_softc(ata_ch
);
165 atapi_cam_reinit_bus(struct ata_channel
*ata_ch
) {
166 struct atapi_xpt_softc
*scp
= get_softc(ata_ch
);
169 * scp might be null if the bus is being reinitialised during
170 * the boot-up sequence, before the ATAPI bus is registered.
174 reinit_bus(scp
, RESET
);
178 reinit_bus(struct atapi_xpt_softc
*scp
, enum reinit_reason reason
) {
179 if (scp
->ata_ch
->devices
& ATA_ATAPI_MASTER
)
180 setup_dev(scp
, &scp
->ata_ch
->device
[MASTER
]);
181 if (scp
->ata_ch
->devices
& ATA_ATAPI_SLAVE
)
182 setup_dev(scp
, &scp
->ata_ch
->device
[SLAVE
]);
186 xpt_async(AC_BUS_RESET
, scp
->path
, NULL
);
189 cam_rescan(scp
->sim
);
195 setup_dev(struct atapi_xpt_softc
*scp
, struct ata_device
*atp
)
197 if (atp
->driver
== NULL
) {
198 ata_set_name(atp
, "atapicam",
199 2 * device_get_unit(atp
->channel
->dev
) +
200 (atp
->unit
== ATA_MASTER
) ? 0 : 1);
201 atp
->driver
= (void *)scp
;
206 setup_async_cb(struct atapi_xpt_softc
*scp
, uint32_t events
)
208 struct ccb_setasync csa
;
210 xpt_setup_ccb(&csa
.ccb_h
, scp
->path
, /*priority*/ 5);
211 csa
.ccb_h
.func_code
= XPT_SASYNC_CB
;
212 csa
.event_enable
= events
;
213 csa
.callback
= &atapi_async
;
214 csa
.callback_arg
= scp
->sim
;
215 xpt_action((union ccb
*) &csa
);
219 atapi_action(struct cam_sim
*sim
, union ccb
*ccb
)
221 struct atapi_xpt_softc
*softc
= (struct atapi_xpt_softc
*)cam_sim_softc(sim
);
222 struct ccb_hdr
*ccb_h
= &ccb
->ccb_h
;
223 struct atapi_hcb
*hcb
= NULL
;
224 int unit
= cam_sim_unit(sim
);
225 int bus
= cam_sim_bus(sim
);
229 switch (ccb_h
->func_code
) {
231 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
233 cpi
->version_num
= 1;
234 cpi
->hba_inquiry
= 0;
235 cpi
->target_sprt
= 0;
236 #if !defined(NO_ATANG)
237 cpi
->hba_misc
= PIM_NO_6_BYTE
;
241 cpi
->hba_eng_cnt
= 0;
242 bzero(cpi
->vuhba_flags
, sizeof(cpi
->vuhba_flags
));
245 cpi
->async_flags
= 0;
247 cpi
->initiator_id
= 7;
248 strncpy(cpi
->sim_vid
, "FreeBSD", sizeof(cpi
->sim_vid
));
249 strncpy(cpi
->hba_vid
, "ATAPI", sizeof(cpi
->hba_vid
));
250 strncpy(cpi
->dev_name
, cam_sim_name(sim
), sizeof cpi
->dev_name
);
251 cpi
->unit_number
= cam_sim_unit(sim
);
252 cpi
->bus_id
= cam_sim_bus(sim
);
253 cpi
->base_transfer_speed
= 3300;
254 cpi
->transport
= XPORT_ATA
;
255 cpi
->transport_version
= 2;
256 cpi
->protocol
= PROTO_SCSI
;
257 cpi
->protocol_version
= SCSI_REV_2
;
258 if (softc
->ata_ch
&& ccb_h
->target_id
!= CAM_TARGET_WILDCARD
) {
259 switch (softc
->ata_ch
->device
[ccb_h
->target_id
].mode
) {
261 cpi
->base_transfer_speed
= 5200;
264 cpi
->base_transfer_speed
= 7000;
267 cpi
->base_transfer_speed
= 11000;
272 cpi
->base_transfer_speed
= 16000;
275 cpi
->base_transfer_speed
= 33000;
278 cpi
->base_transfer_speed
= 66000;
281 cpi
->base_transfer_speed
= 100000;
284 cpi
->base_transfer_speed
= 133000;
290 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
295 case XPT_RESET_DEV
: {
296 int tid
= ccb_h
->target_id
;
297 struct ata_device
*dev
= get_ata_device(softc
, tid
);
299 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
, ("dev reset\n"));
301 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
307 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
, ("bus reset\n"));
308 ata_reinit(softc
->ata_ch
);
309 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
313 case XPT_SET_TRAN_SETTINGS
:
314 /* ignore these, we're not doing SCSI here */
315 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
,
316 ("SET_TRAN_SETTINGS not supported\n"));
317 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
321 case XPT_GET_TRAN_SETTINGS
: {
322 struct ccb_trans_settings
*cts
= &ccb
->cts
;
323 cts
->protocol
= PROTO_SCSI
;
324 cts
->protocol_version
= SCSI_REV_2
;
325 cts
->transport
= XPORT_ATA
;
326 cts
->transport_version
= XPORT_VERSION_UNSPECIFIED
;
327 cts
->proto_specific
.valid
= 0;
328 cts
->xport_specific
.valid
= 0;
329 /* nothing more to do */
330 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
331 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
, ("GET_TRAN_SETTINGS\n"));
336 case XPT_CALC_GEOMETRY
: {
337 struct ccb_calc_geometry
*ccg
;
338 unsigned int size_mb
;
339 unsigned int secs_per_cylinder
;
342 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
, ("CALC_GEOMETRY\n"));
344 size_mb
= ccg
->volume_size
/ ((1024L * 1024L) / ccg
->block_size
);
347 if (size_mb
> 1024 && extended
) {
349 ccg
->secs_per_track
= 63;
352 ccg
->secs_per_track
= 32;
354 secs_per_cylinder
= ccg
->heads
* ccg
->secs_per_track
;
355 ccg
->cylinders
= ccg
->volume_size
/ secs_per_cylinder
;
356 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
362 struct ccb_scsiio
*csio
= &ccb
->csio
;
363 int tid
= ccb_h
->target_id
, lid
= ccb_h
->target_lun
;
364 struct ata_device
*dev
= get_ata_device(softc
, tid
);
366 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
, ("XPT_SCSI_IO\n"));
368 /* check that this request was not aborted already */
369 if ((ccb_h
->status
& CAM_STATUS_MASK
) != CAM_REQ_INPROG
) {
370 kprintf("XPT_SCSI_IO received but already in progress?\n");
375 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
,
376 ("SCSI IO received for invalid device\n"));
377 ccb_h
->status
= CAM_TID_INVALID
;
382 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
,
383 ("SCSI IO received for invalid lun %d\n", lid
));
384 ccb_h
->status
= CAM_LUN_INVALID
;
388 if ((ccb_h
->flags
& CAM_SCATTER_VALID
)) {
389 /* scatter-gather not supported */
390 xpt_print_path(ccb_h
->path
);
391 kprintf("ATAPI-CAM does not support scatter-gather yet!\n");
394 if ((hcb
= allocate_hcb(softc
, unit
, bus
, ccb
)) == NULL
)
397 ccb_h
->status
|= CAM_SIM_QUEUED
;
399 bcopy((ccb_h
->flags
& CAM_CDB_POINTER
) ?
400 csio
->cdb_io
.cdb_ptr
: csio
->cdb_io
.cdb_bytes
,
401 hcb
->cmd
, csio
->cdb_len
);
403 if (CAM_DEBUGGED(ccb_h
->path
, CAM_DEBUG_CDB
)) {
404 char cdb_str
[(SCSI_MAX_CDBLEN
* 3) + 1];
406 kprintf("atapi_action: hcb@%p: %s\n", hcb
,
407 scsi_cdb_string(hcb
->cmd
, cdb_str
, sizeof(cdb_str
)));
411 len
= csio
->dxfer_len
;
412 buf
= csio
->data_ptr
;
414 /* some SCSI commands require special processing */
415 switch (hcb
->cmd
[0]) {
418 * many ATAPI devices seem to report more than
419 * SHORT_INQUIRY_LENGTH bytes of available INQUIRY
420 * information, but respond with some incorrect condition
421 * when actually asked for it, so we are going to pretend
422 * that only SHORT_INQUIRY_LENGTH are expected, anyway.
424 struct scsi_inquiry
*inq
= (struct scsi_inquiry
*) &hcb
->cmd
[0];
426 if (inq
->byte2
== 0 && inq
->page_code
== 0 &&
427 inq
->length
> SHORT_INQUIRY_LENGTH
) {
429 len
= inq
->length
= SHORT_INQUIRY_LENGTH
;
433 #if defined(NO_ATANG) /* EXITED IN ORIGINAL, DELETED IN ATANG */
439 * not supported by ATAPI/MMC devices (per SCSI MMC spec)
440 * translate to _10 equivalent.
441 * (actually we should do this only if we have tried
442 * MODE_foo_6 and received ILLEGAL_REQUEST or
443 * INVALID COMMAND OPERATION CODE)
444 * alternative fix: behave like a honest CAM transport,
445 * do not muck with CDB contents, and change scsi_cd to
446 * always use MODE_SENSE_10 in cdgetmode(), or let scsi_cd
447 * know that this specific unit is an ATAPI/MMC one,
448 * and in /that case/ use MODE_SENSE_10
451 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
,
452 ("Translating %s into _10 equivalent\n",
453 (hcb
->cmd
[0] == MODE_SELECT_6
) ?
454 "MODE_SELECT_6" : "MODE_SENSE_6"));
458 hcb
->cmd
[8] = hcb
->cmd
[4];
459 hcb
->cmd
[9] = hcb
->cmd
[5];
469 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
,
470 ("Translating %s into _10 equivalent\n",
471 (hcb
->cmd
[0] == READ_6
) ? "READ_6" : "WRITE_6"));
473 hcb
->cmd
[9] = hcb
->cmd
[5];
474 hcb
->cmd
[8] = hcb
->cmd
[4];
477 hcb
->cmd
[5] = hcb
->cmd
[3];
478 hcb
->cmd
[4] = hcb
->cmd
[2];
479 hcb
->cmd
[3] = hcb
->cmd
[1] & 0x1f;
485 if ((ccb_h
->flags
& CAM_DIR_MASK
) == CAM_DIR_IN
&& (len
& 1)) {
486 /* ATA always transfers an even number of bytes */
488 buf
= hcb
->dxfer_alloc
= kmalloc(len
, M_ATACAM
, M_INTWAIT
| M_ZERO
);
491 TAILQ_INSERT_TAIL(&softc
->pending_hcbs
, hcb
, chain
);
493 if (atapi_queue_cmd(dev
, hcb
->cmd
, buf
, len
,
494 (((ccb_h
->flags
& CAM_DIR_MASK
) == CAM_DIR_IN
) ?
495 ATPR_F_READ
: 0) | ATPR_F_QUIET
,
496 ccb_h
->timeout
, atapi_cb
, (void *)hcb
) == 0)
502 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_SUBTRACE
,
503 ("unsupported function code 0x%02x\n", ccb_h
->func_code
));
504 ccb_h
->status
= CAM_REQ_INVALID
;
512 xpt_print_path(ccb_h
->path
);
513 kprintf("out of memory, freezing queue.\n");
514 softc
->flags
|= RESOURCE_SHORTAGE
;
515 xpt_freeze_simq(sim
, /*count*/ 1);
516 ccb_h
->status
= CAM_REQUEUE_REQ
;
521 atapi_poll(struct cam_sim
*sim
)
523 /* do nothing - we do not actually service any interrupts */
524 kprintf("atapi_poll called!\n");
528 atapi_cb(struct atapi_request
*req
)
530 struct atapi_hcb
*hcb
= (struct atapi_hcb
*) req
->driver
;
531 struct ccb_scsiio
*csio
= &hcb
->ccb
->csio
;
532 int hcb_status
= req
->result
;
536 if (CAM_DEBUGGED(csio
->ccb_h
.path
, CAM_DEBUG_CDB
)) {
537 kprintf("atapi_cb: hcb@%p status = %02x: (sk = %02x%s%s%s)\n",
538 hcb
, hcb_status
, hcb_status
>> 4,
539 (hcb_status
& 4) ? " ABRT" : "",
540 (hcb_status
& 2) ? " EOM" : "",
541 (hcb_status
& 1) ? " ILI" : "");
542 kprintf(" %s: cmd %02x - sk=%02x asc=%02x ascq=%02x\n",
543 req
->device
->name
, req
->ccb
[0], req
->sense
.sense_key
,
544 req
->sense
.asc
, req
->sense
.ascq
);
547 if (hcb_status
!= 0) {
548 csio
->scsi_status
= SCSI_STATUS_CHECK_COND
;
549 if ((csio
->ccb_h
.flags
& CAM_DIS_AUTOSENSE
) == 0) {
550 csio
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
551 bcopy((void *)&req
->sense
, (void *)&csio
->sense_data
,
552 sizeof(struct atapi_reqsense
));
554 free_hcb_and_ccb_done(hcb
, CAM_SCSI_STATUS_ERROR
);
557 if (((csio
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
) &&
558 hcb
->dxfer_alloc
!= NULL
)
559 bcopy(hcb
->dxfer_alloc
, csio
->data_ptr
, csio
->dxfer_len
);
560 csio
->scsi_status
= SCSI_STATUS_OK
;
561 free_hcb_and_ccb_done(hcb
, CAM_REQ_CMP
);
568 free_hcb_and_ccb_done(struct atapi_hcb
*hcb
, u_int32_t status
)
570 struct atapi_xpt_softc
*softc
= hcb
->softc
;
571 union ccb
*ccb
= hcb
->ccb
;
574 /* we're about to free a hcb, so the shortage has ended */
575 if (softc
->flags
& RESOURCE_SHORTAGE
) {
576 softc
->flags
&= ~RESOURCE_SHORTAGE
;
577 status
|= CAM_RELEASE_SIMQ
;
582 status
| (ccb
->ccb_h
.status
& ~(CAM_STATUS_MASK
| CAM_SIM_QUEUED
));
587 atapi_async(void *callback_arg
, u_int32_t code
,
588 struct cam_path
*path
, void *arg
)
591 atapi_async1(callback_arg
, code
, path
, arg
);
596 atapi_async1(void *callback_arg
, u_int32_t code
,
597 struct cam_path
* path
, void *arg
)
599 struct atapi_xpt_softc
*softc
;
603 sim
= (struct cam_sim
*) callback_arg
;
604 softc
= (struct atapi_xpt_softc
*) cam_sim_softc(sim
);
607 targ
= xpt_path_target_id(path
);
608 xpt_print_path(path
);
610 kprintf("Lost host adapter\n");
612 kprintf("Lost target %d???\n", targ
);
621 cam_rescan_callback(struct cam_periph
*periph
, union ccb
*ccb
)
623 if (ccb
->ccb_h
.status
!= CAM_REQ_CMP
) {
624 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
625 ("Rescan failed, 0x%04x\n", ccb
->ccb_h
.status
));
627 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
628 ("Rescan succeeded\n"));
630 xpt_free_path(ccb
->ccb_h
.path
);
631 kfree(ccb
, M_ATACAM
);
635 cam_rescan(struct cam_sim
*sim
)
637 struct cam_path
*path
;
638 union ccb
*ccb
= kmalloc(sizeof(union ccb
), M_ATACAM
, M_INTWAIT
| M_ZERO
);
640 if (xpt_create_path(&path
, xpt_periph
, cam_sim_path(sim
),
641 CAM_TARGET_WILDCARD
, CAM_LUN_WILDCARD
) != CAM_REQ_CMP
)
644 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("Rescanning ATAPI bus.\n"));
645 xpt_setup_ccb(&ccb
->ccb_h
, path
, 5/*priority (low)*/);
646 ccb
->ccb_h
.func_code
= XPT_SCAN_BUS
;
647 ccb
->ccb_h
.cbfcnp
= cam_rescan_callback
;
648 ccb
->crcn
.flags
= CAM_FLAG_NONE
;
650 /* scan is in progress now */
653 static struct atapi_hcb
*
654 allocate_hcb(struct atapi_xpt_softc
*softc
, int unit
, int bus
, union ccb
*ccb
)
656 struct atapi_hcb
*hcb
;
658 hcb
= kmalloc(sizeof(struct atapi_hcb
), M_ATACAM
, M_INTWAIT
| M_ZERO
);
670 free_hcb(struct atapi_hcb
*hcb
)
672 TAILQ_REMOVE(&hcb
->softc
->pending_hcbs
, hcb
, chain
);
673 if (hcb
->dxfer_alloc
!= NULL
)
674 kfree(hcb
->dxfer_alloc
, M_ATACAM
);
675 kfree(hcb
, M_ATACAM
);
679 free_softc(struct atapi_xpt_softc
*scp
)
681 struct atapi_hcb
*hcb
;
684 TAILQ_FOREACH(hcb
, &scp
->pending_hcbs
, chain
) {
685 free_hcb_and_ccb_done(hcb
, CAM_UNREC_HBA_ERROR
);
687 if (scp
->path
!= NULL
) {
688 setup_async_cb(scp
, 0);
689 xpt_free_path(scp
->path
);
691 if ((scp
->flags
& BUS_REGISTERED
) != 0) {
692 if (xpt_bus_deregister(cam_sim_path(scp
->sim
)) == CAM_REQ_CMP
)
693 scp
->flags
&= ~BUS_REGISTERED
;
695 if (scp
->sim
!= NULL
) {
696 if ((scp
->flags
& BUS_REGISTERED
) == 0)
697 cam_sim_free(scp
->sim
);
699 kprintf("Can't free %s SIM (still registered)\n",
700 cam_sim_name(scp
->sim
));
702 LIST_REMOVE(scp
, chain
);
703 kfree(scp
, M_ATACAM
);
707 static struct atapi_xpt_softc
*
708 get_softc(struct ata_channel
*ata_ch
) {
709 struct atapi_xpt_softc
*scp
;
710 LIST_FOREACH(scp
, &all_buses
, chain
) {
711 if (scp
->ata_ch
== ata_ch
)
717 static struct ata_device
*
718 get_ata_device(struct atapi_xpt_softc
*scp
, int id
)
720 int role
= ATA_ATAPI_MASTER
;
724 role
= ATA_ATAPI_SLAVE
;
728 if (scp
->ata_ch
->devices
& role
)
729 return &scp
->ata_ch
->device
[id
];