Move rtems/freebsd to freebsd and contrib to freebsd/contrib

This commit is contained in:
Joel Sherrill
2012-03-08 07:25:21 -06:00
parent af079f3ab6
commit e2d2bf579b
758 changed files with 0 additions and 0 deletions

127
freebsd/cam/ata/ata_all.h Normal file
View File

@@ -0,0 +1,127 @@
/*-
* Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef CAM_ATA_ALL_H
#define CAM_ATA_ALL_H 1
#include <rtems/freebsd/sys/ata.h>
struct ccb_ataio;
struct cam_periph;
union ccb;
struct ata_cmd {
u_int8_t flags; /* ATA command flags */
#define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */
#define CAM_ATAIO_FPDMA 0x02 /* FPDMA command */
#define CAM_ATAIO_CONTROL 0x04 /* Control, not a command */
#define CAM_ATAIO_NEEDRESULT 0x08 /* Request requires result. */
#define CAM_ATAIO_DMA 0x10 /* DMA command */
u_int8_t command;
u_int8_t features;
u_int8_t lba_low;
u_int8_t lba_mid;
u_int8_t lba_high;
u_int8_t device;
u_int8_t lba_low_exp;
u_int8_t lba_mid_exp;
u_int8_t lba_high_exp;
u_int8_t features_exp;
u_int8_t sector_count;
u_int8_t sector_count_exp;
u_int8_t control;
};
struct ata_res {
u_int8_t flags; /* ATA command flags */
#define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */
u_int8_t status;
u_int8_t error;
u_int8_t lba_low;
u_int8_t lba_mid;
u_int8_t lba_high;
u_int8_t device;
u_int8_t lba_low_exp;
u_int8_t lba_mid_exp;
u_int8_t lba_high_exp;
u_int8_t sector_count;
u_int8_t sector_count_exp;
};
int ata_version(int ver);
char * ata_op_string(struct ata_cmd *cmd);
char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len);
char * ata_res_string(struct ata_res *res, char *res_string, size_t len);
int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
void ata_print_ident(struct ata_params *ident_data);
uint32_t ata_logical_sector_size(struct ata_params *ident_data);
uint64_t ata_physical_sector_size(struct ata_params *ident_data);
uint64_t ata_logical_sector_offset(struct ata_params *ident_data);
void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
uint32_t lba, uint8_t sector_count);
void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
uint64_t lba, uint16_t sector_count);
void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
uint64_t lba, uint16_t sector_count);
void ata_reset_cmd(struct ccb_ataio *ataio);
void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port);
void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val);
void ata_bswap(int8_t *buf, int len);
void ata_btrim(int8_t *buf, int len);
void ata_bpack(int8_t *src, int8_t *dst, int len);
int ata_max_pmode(struct ata_params *ap);
int ata_max_wmode(struct ata_params *ap);
int ata_max_umode(struct ata_params *ap);
int ata_max_mode(struct ata_params *ap, int maxmode);
char * ata_mode2string(int mode);
int ata_string2mode(char *str);
u_int ata_mode2speed(int mode);
u_int ata_revision2speed(int revision);
int ata_speed2revision(u_int speed);
int ata_identify_match(caddr_t identbuffer, caddr_t table_entry);
int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
#endif

438
freebsd/cam/cam.c Normal file
View File

@@ -0,0 +1,438 @@
#include <rtems/freebsd/machine/rtems-bsd-config.h>
/*-
* Generic utility routines for the Common Access Method layer.
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <rtems/freebsd/sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <rtems/freebsd/sys/param.h>
#ifdef _KERNEL
#include <rtems/freebsd/sys/systm.h>
#include <rtems/freebsd/sys/kernel.h>
#include <rtems/freebsd/sys/sysctl.h>
#else /* _KERNEL */
#include <rtems/freebsd/stdlib.h>
#include <rtems/freebsd/stdio.h>
#include <rtems/freebsd/camlib.h>
#endif /* _KERNEL */
#include <rtems/freebsd/cam/cam.h>
#include <rtems/freebsd/cam/cam_ccb.h>
#include <rtems/freebsd/cam/scsi/scsi_all.h>
#include <rtems/freebsd/sys/sbuf.h>
#ifdef _KERNEL
#include <rtems/freebsd/sys/libkern.h>
#include <rtems/freebsd/cam/cam_queue.h>
#include <rtems/freebsd/cam/cam_xpt.h>
#endif
static int camstatusentrycomp(const void *key, const void *member);
const struct cam_status_entry cam_status_table[] = {
{ CAM_REQ_INPROG, "CCB request is in progress" },
{ CAM_REQ_CMP, "CCB request completed without error" },
{ CAM_REQ_ABORTED, "CCB request aborted by the host" },
{ CAM_UA_ABORT, "Unable to abort CCB request" },
{ CAM_REQ_CMP_ERR, "CCB request completed with an error" },
{ CAM_BUSY, "CAM subsystem is busy" },
{ CAM_REQ_INVALID, "CCB request was invalid" },
{ CAM_PATH_INVALID, "Supplied Path ID is invalid" },
{ CAM_DEV_NOT_THERE, "Device Not Present" },
{ CAM_UA_TERMIO, "Unable to terminate I/O CCB request" },
{ CAM_SEL_TIMEOUT, "Selection Timeout" },
{ CAM_CMD_TIMEOUT, "Command timeout" },
{ CAM_SCSI_STATUS_ERROR, "SCSI Status Error" },
{ CAM_MSG_REJECT_REC, "Message Reject Reveived" },
{ CAM_SCSI_BUS_RESET, "SCSI Bus Reset Sent/Received" },
{ CAM_UNCOR_PARITY, "Uncorrectable parity/CRC error" },
{ CAM_AUTOSENSE_FAIL, "Auto-Sense Retrieval Failed" },
{ CAM_NO_HBA, "No HBA Detected" },
{ CAM_DATA_RUN_ERR, "Data Overrun error" },
{ CAM_UNEXP_BUSFREE, "Unexpected Bus Free" },
{ CAM_SEQUENCE_FAIL, "Target Bus Phase Sequence Failure" },
{ CAM_CCB_LEN_ERR, "CCB length supplied is inadequate" },
{ CAM_PROVIDE_FAIL, "Unable to provide requested capability" },
{ CAM_BDR_SENT, "SCSI BDR Message Sent" },
{ CAM_REQ_TERMIO, "CCB request terminated by the host" },
{ CAM_UNREC_HBA_ERROR, "Unrecoverable Host Bus Adapter Error" },
{ CAM_REQ_TOO_BIG, "The request was too large for this host" },
{ CAM_REQUEUE_REQ, "Unconditionally Re-queue Request", },
{ CAM_ATA_STATUS_ERROR, "ATA Status Error" },
{ CAM_IDE, "Initiator Detected Error Message Received" },
{ CAM_RESRC_UNAVAIL, "Resource Unavailable" },
{ CAM_UNACKED_EVENT, "Unacknowledged Event by Host" },
{ CAM_MESSAGE_RECV, "Message Received in Host Target Mode" },
{ CAM_INVALID_CDB, "Invalid CDB received in Host Target Mode" },
{ CAM_LUN_INVALID, "Invalid Lun" },
{ CAM_TID_INVALID, "Invalid Target ID" },
{ CAM_FUNC_NOTAVAIL, "Function Not Available" },
{ CAM_NO_NEXUS, "Nexus Not Established" },
{ CAM_IID_INVALID, "Invalid Initiator ID" },
{ CAM_CDB_RECVD, "CDB Received" },
{ CAM_LUN_ALRDY_ENA, "LUN Already Enabled for Target Mode" },
{ CAM_SCSI_BUSY, "SCSI Bus Busy" },
};
const int num_cam_status_entries =
sizeof(cam_status_table)/sizeof(*cam_status_table);
#ifdef _KERNEL
SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
#endif
void
cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
{
/* Trim leading/trailing spaces, nulls. */
while (srclen > 0 && src[0] == ' ')
src++, srclen--;
while (srclen > 0
&& (src[srclen-1] == ' ' || src[srclen-1] == '\0'))
srclen--;
while (srclen > 0 && dstlen > 1) {
u_int8_t *cur_pos = dst;
if (*src < 0x20 || *src >= 0x80) {
/* SCSI-II Specifies that these should never occur. */
/* non-printable character */
if (dstlen > 4) {
*cur_pos++ = '\\';
*cur_pos++ = ((*src & 0300) >> 6) + '0';
*cur_pos++ = ((*src & 0070) >> 3) + '0';
*cur_pos++ = ((*src & 0007) >> 0) + '0';
} else {
*cur_pos++ = '?';
}
} else {
/* normal character */
*cur_pos++ = *src;
}
src++;
srclen--;
dstlen -= cur_pos - dst;
dst = cur_pos;
}
*dst = '\0';
}
/*
* Compare string with pattern, returning 0 on match.
* Short pattern matches trailing blanks in name,
* wildcard '*' in pattern matches rest of name,
* wildcard '?' matches a single non-space character.
*/
int
cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len)
{
while (*pattern != '\0'&& str_len > 0) {
if (*pattern == '*') {
return (0);
}
if ((*pattern != *str)
&& (*pattern != '?' || *str == ' ')) {
return (1);
}
pattern++;
str++;
str_len--;
}
while (str_len > 0 && *str == ' ') {
str++;
str_len--;
}
if (str_len > 0 && *str == 0)
str_len = 0;
return (str_len);
}
caddr_t
cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
int entry_size, cam_quirkmatch_t *comp_func)
{
for (; num_entries > 0; num_entries--, quirk_table += entry_size) {
if ((*comp_func)(target, quirk_table) == 0)
return (quirk_table);
}
return (NULL);
}
const struct cam_status_entry*
cam_fetch_status_entry(cam_status status)
{
status &= CAM_STATUS_MASK;
return (bsearch(&status, &cam_status_table,
num_cam_status_entries,
sizeof(*cam_status_table),
camstatusentrycomp));
}
static int
camstatusentrycomp(const void *key, const void *member)
{
cam_status status;
const struct cam_status_entry *table_entry;
status = *(const cam_status *)key;
table_entry = (const struct cam_status_entry *)member;
return (status - table_entry->status_code);
}
#ifndef __rtems__
#ifdef _KERNEL
char *
cam_error_string(union ccb *ccb, char *str, int str_len,
cam_error_string_flags flags,
cam_error_proto_flags proto_flags)
#else /* !_KERNEL */
char *
cam_error_string(struct cam_device *device, union ccb *ccb, char *str,
int str_len, cam_error_string_flags flags,
cam_error_proto_flags proto_flags)
#endif /* _KERNEL/!_KERNEL */
{
char path_str[64];
struct sbuf sb;
if ((ccb == NULL)
|| (str == NULL)
|| (str_len <= 0))
return(NULL);
if (flags == CAM_ESF_NONE)
return(NULL);
switch (ccb->ccb_h.func_code) {
case XPT_ATA_IO:
switch (proto_flags & CAM_EPF_LEVEL_MASK) {
case CAM_EPF_NONE:
break;
case CAM_EPF_ALL:
case CAM_EPF_NORMAL:
proto_flags |= CAM_EAF_PRINT_RESULT;
/* FALLTHROUGH */
case CAM_EPF_MINIMAL:
proto_flags |= CAM_EAF_PRINT_STATUS;
/* FALLTHROUGH */
default:
break;
}
break;
case XPT_SCSI_IO:
switch (proto_flags & CAM_EPF_LEVEL_MASK) {
case CAM_EPF_NONE:
break;
case CAM_EPF_ALL:
case CAM_EPF_NORMAL:
proto_flags |= CAM_ESF_PRINT_SENSE;
/* FALLTHROUGH */
case CAM_EPF_MINIMAL:
proto_flags |= CAM_ESF_PRINT_STATUS;
/* FALLTHROUGH */
default:
break;
}
break;
default:
break;
}
#ifdef _KERNEL
xpt_path_string(ccb->csio.ccb_h.path, path_str, sizeof(path_str));
#else /* !_KERNEL */
cam_path_string(device, path_str, sizeof(path_str));
#endif /* _KERNEL/!_KERNEL */
sbuf_new(&sb, str, str_len, 0);
if (flags & CAM_ESF_COMMAND) {
sbuf_cat(&sb, path_str);
switch (ccb->ccb_h.func_code) {
case XPT_ATA_IO:
ata_command_sbuf(&ccb->ataio, &sb);
sbuf_printf(&sb, "\n");
break;
case XPT_SCSI_IO:
#ifdef _KERNEL
scsi_command_string(&ccb->csio, &sb);
#else /* !_KERNEL */
scsi_command_string(device, &ccb->csio, &sb);
#endif /* _KERNEL/!_KERNEL */
sbuf_printf(&sb, "\n");
break;
default:
break;
}
}
if (flags & CAM_ESF_CAM_STATUS) {
cam_status status;
const struct cam_status_entry *entry;
sbuf_cat(&sb, path_str);
status = ccb->ccb_h.status & CAM_STATUS_MASK;
entry = cam_fetch_status_entry(status);
if (entry == NULL)
sbuf_printf(&sb, "CAM status: Unknown (%#x)\n",
ccb->ccb_h.status);
else
sbuf_printf(&sb, "CAM status: %s\n",
entry->status_text);
}
if (flags & CAM_ESF_PROTO_STATUS) {
switch (ccb->ccb_h.func_code) {
case XPT_ATA_IO:
if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
CAM_ATA_STATUS_ERROR)
break;
if (proto_flags & CAM_EAF_PRINT_STATUS) {
sbuf_cat(&sb, path_str);
ata_status_sbuf(&ccb->ataio, &sb);
sbuf_printf(&sb, "\n");
}
if (proto_flags & CAM_EAF_PRINT_RESULT) {
sbuf_cat(&sb, path_str);
ata_res_sbuf(&ccb->ataio, &sb);
sbuf_printf(&sb, "\n");
}
break;
case XPT_SCSI_IO:
if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
CAM_SCSI_STATUS_ERROR)
break;
if (proto_flags & CAM_ESF_PRINT_STATUS) {
sbuf_cat(&sb, path_str);
sbuf_printf(&sb, "SCSI status: %s\n",
scsi_status_string(&ccb->csio));
}
if ((proto_flags & CAM_ESF_PRINT_SENSE)
&& (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
&& (ccb->ccb_h.status & CAM_AUTOSNS_VALID)) {
#ifdef _KERNEL
scsi_sense_sbuf(&ccb->csio, &sb,
SSS_FLAG_NONE);
#else /* !_KERNEL */
scsi_sense_sbuf(device, &ccb->csio, &sb,
SSS_FLAG_NONE);
#endif /* _KERNEL/!_KERNEL */
}
break;
default:
break;
}
}
sbuf_finish(&sb);
return(sbuf_data(&sb));
}
#ifdef _KERNEL
void
cam_error_print(union ccb *ccb, cam_error_string_flags flags,
cam_error_proto_flags proto_flags)
{
char str[512];
printf("%s", cam_error_string(ccb, str, sizeof(str), flags,
proto_flags));
}
#else /* !_KERNEL */
void
cam_error_print(struct cam_device *device, union ccb *ccb,
cam_error_string_flags flags, cam_error_proto_flags proto_flags,
FILE *ofile)
{
char str[512];
if ((device == NULL) || (ccb == NULL) || (ofile == NULL))
return;
fprintf(ofile, "%s", cam_error_string(device, ccb, str, sizeof(str),
flags, proto_flags));
}
#endif /* _KERNEL/!_KERNEL */
/*
* Common calculate geometry fuction
*
* Caller should set ccg->volume_size and block_size.
* The extended parameter should be zero if extended translation
* should not be used.
*/
void
cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended)
{
uint32_t size_mb, secs_per_cylinder;
if (ccg->block_size == 0) {
ccg->ccb_h.status = CAM_REQ_CMP_ERR;
return;
}
size_mb = (1024L * 1024L) / ccg->block_size;
if (size_mb == 0) {
ccg->ccb_h.status = CAM_REQ_CMP_ERR;
return;
}
size_mb = ccg->volume_size / size_mb;
if (size_mb > 1024 && extended) {
ccg->heads = 255;
ccg->secs_per_track = 63;
} else {
ccg->heads = 64;
ccg->secs_per_track = 32;
}
secs_per_cylinder = ccg->heads * ccg->secs_per_track;
if (secs_per_cylinder == 0) {
ccg->ccb_h.status = CAM_REQ_CMP_ERR;
return;
}
ccg->cylinders = ccg->volume_size / secs_per_cylinder;
ccg->ccb_h.status = CAM_REQ_CMP;
}
#endif /* __rtems__ */

263
freebsd/cam/cam.h Normal file
View File

@@ -0,0 +1,263 @@
/*-
* Data structures and definitions for the CAM system.
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_H
#define _CAM_CAM_H 1
#ifdef _KERNEL
#ifndef __rtems__
#include <rtems/freebsd/opt_cam.h>
#else /* __rtems__ */
#include <rtems/freebsd/local/opt_cam.h>
#endif /* __rtems__ */
#endif
#include <rtems/freebsd/sys/cdefs.h>
typedef u_int path_id_t;
typedef u_int target_id_t;
typedef u_int lun_id_t;
#define CAM_XPT_PATH_ID ((path_id_t)~0)
#define CAM_BUS_WILDCARD ((path_id_t)~0)
#define CAM_TARGET_WILDCARD ((target_id_t)~0)
#define CAM_LUN_WILDCARD ((lun_id_t)~0)
/*
* Maximum length for a CAM CDB.
*/
#define CAM_MAX_CDBLEN 16
/*
* Definition of a CAM peripheral driver entry. Peripheral drivers instantiate
* one of these for each device they wish to communicate with and pass it into
* the xpt layer when they wish to schedule work on that device via the
* xpt_schedule API.
*/
struct cam_periph;
/*
* Priority information for a CAM structure.
*/
typedef enum {
CAM_RL_HOST,
CAM_RL_BUS,
CAM_RL_XPT,
CAM_RL_DEV,
CAM_RL_NORMAL,
CAM_RL_VALUES
} cam_rl;
/*
* The generation number is incremented everytime a new entry is entered into
* the queue giving round robin per priority level scheduling.
*/
typedef struct {
u_int32_t priority;
#define CAM_PRIORITY_HOST ((CAM_RL_HOST << 8) + 0x80)
#define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80)
#define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80)
#define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80)
#define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80)
#define CAM_PRIORITY_NONE (u_int32_t)-1
#define CAM_PRIORITY_TO_RL(x) ((x) >> 8)
u_int32_t generation;
int index;
#define CAM_UNQUEUED_INDEX -1
#define CAM_ACTIVE_INDEX -2
#define CAM_DONEQ_INDEX -3
} cam_pinfo;
/*
* Macro to compare two generation numbers. It is used like this:
*
* if (GENERATIONCMP(a, >=, b))
* ...;
*
* GERERATIONCMP uses modular arithmetic to guard against wraps
* wraps in the generation number.
*/
#define GENERATIONCMP(x, op, y) ((int32_t)((x) - (y)) op 0)
/* CAM flags XXX Move to cam_periph.h ??? */
typedef enum {
CAM_FLAG_NONE = 0x00,
CAM_EXPECT_INQ_CHANGE = 0x01,
CAM_RETRY_SELTO = 0x02 /* Retry Selection Timeouts */
} cam_flags;
/* CAM Status field values */
typedef enum {
CAM_REQ_INPROG, /* CCB request is in progress */
CAM_REQ_CMP, /* CCB request completed without error */
CAM_REQ_ABORTED, /* CCB request aborted by the host */
CAM_UA_ABORT, /* Unable to abort CCB request */
CAM_REQ_CMP_ERR, /* CCB request completed with an error */
CAM_BUSY, /* CAM subsystem is busy */
CAM_REQ_INVALID, /* CCB request was invalid */
CAM_PATH_INVALID, /* Supplied Path ID is invalid */
CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */
CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */
CAM_SEL_TIMEOUT, /* Target Selection Timeout */
CAM_CMD_TIMEOUT, /* Command timeout */
CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */
CAM_MSG_REJECT_REC, /* Message Reject Received */
CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */
CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */
CAM_AUTOSENSE_FAIL = 0x10,/* Autosense: request sense cmd fail */
CAM_NO_HBA, /* No HBA Detected error */
CAM_DATA_RUN_ERR, /* Data Overrun error */
CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */
CAM_SEQUENCE_FAIL, /* Target Bus Phase Sequence Failure */
CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */
CAM_PROVIDE_FAIL, /* Unable to provide requested capability */
CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */
CAM_REQ_TERMIO, /* CCB request terminated by the host */
CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */
CAM_REQ_TOO_BIG, /* The request was too large for this host */
CAM_REQUEUE_REQ, /*
* This request should be requeued to preserve
* transaction ordering. This typically occurs
* when the SIM recognizes an error that should
* freeze the queue and must place additional
* requests for the target at the sim level
* back into the XPT queue.
*/
CAM_ATA_STATUS_ERROR, /* ATA error, look at error code in CCB */
CAM_SCSI_IT_NEXUS_LOST, /* Initiator/Target Nexus lost. */
CAM_IDE = 0x33, /* Initiator Detected Error */
CAM_RESRC_UNAVAIL, /* Resource Unavailable */
CAM_UNACKED_EVENT, /* Unacknowledged Event by Host */
CAM_MESSAGE_RECV, /* Message Received in Host Target Mode */
CAM_INVALID_CDB, /* Invalid CDB received in Host Target Mode */
CAM_LUN_INVALID, /* Lun supplied is invalid */
CAM_TID_INVALID, /* Target ID supplied is invalid */
CAM_FUNC_NOTAVAIL, /* The requested function is not available */
CAM_NO_NEXUS, /* Nexus is not established */
CAM_IID_INVALID, /* The initiator ID is invalid */
CAM_CDB_RECVD, /* The SCSI CDB has been received */
CAM_LUN_ALRDY_ENA, /* The LUN is already enabled for target mode */
CAM_SCSI_BUSY, /* SCSI Bus Busy */
CAM_DEV_QFRZN = 0x40, /* The DEV queue is frozen w/this err */
/* Autosense data valid for target */
CAM_AUTOSNS_VALID = 0x80,
CAM_RELEASE_SIMQ = 0x100,/* SIM ready to take more commands */
CAM_SIM_QUEUED = 0x200,/* SIM has this command in it's queue */
CAM_STATUS_MASK = 0x3F, /* Mask bits for just the status # */
/* Target Specific Adjunct Status */
CAM_SENT_SENSE = 0x40000000 /* sent sense with status */
} cam_status;
typedef enum {
CAM_ESF_NONE = 0x00,
CAM_ESF_COMMAND = 0x01,
CAM_ESF_CAM_STATUS = 0x02,
CAM_ESF_PROTO_STATUS = 0x04,
CAM_ESF_ALL = 0xff
} cam_error_string_flags;
typedef enum {
CAM_EPF_NONE = 0x00,
CAM_EPF_MINIMAL = 0x01,
CAM_EPF_NORMAL = 0x02,
CAM_EPF_ALL = 0x03,
CAM_EPF_LEVEL_MASK = 0x0f
/* All bits above bit 3 are protocol-specific */
} cam_error_proto_flags;
typedef enum {
CAM_ESF_PRINT_NONE = 0x00,
CAM_ESF_PRINT_STATUS = 0x10,
CAM_ESF_PRINT_SENSE = 0x20
} cam_error_scsi_flags;
typedef enum {
CAM_EAF_PRINT_NONE = 0x00,
CAM_EAF_PRINT_STATUS = 0x10,
CAM_EAF_PRINT_RESULT = 0x20
} cam_error_ata_flags;
struct cam_status_entry
{
cam_status status_code;
const char *status_text;
};
extern const struct cam_status_entry cam_status_table[];
extern const int num_cam_status_entries;
union ccb;
#ifdef SYSCTL_DECL /* from sysctl.h */
SYSCTL_DECL(_kern_cam);
#endif
__BEGIN_DECLS
typedef int (cam_quirkmatch_t)(caddr_t, caddr_t);
caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
int entry_size, cam_quirkmatch_t *comp_func);
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen);
int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len);
const struct cam_status_entry*
cam_fetch_status_entry(cam_status status);
#ifdef _KERNEL
char * cam_error_string(union ccb *ccb, char *str, int str_len,
cam_error_string_flags flags,
cam_error_proto_flags proto_flags);
void cam_error_print(union ccb *ccb, cam_error_string_flags flags,
cam_error_proto_flags proto_flags);
#else /* _KERNEL */
struct cam_device;
char * cam_error_string(struct cam_device *device, union ccb *ccb, char *str,
int str_len, cam_error_string_flags flags,
cam_error_proto_flags proto_flags);
void cam_error_print(struct cam_device *device, union ccb *ccb,
cam_error_string_flags flags,
cam_error_proto_flags proto_flags, FILE *ofile);
#endif /* _KERNEL */
__END_DECLS
#ifdef _KERNEL
static __inline void cam_init_pinfo(cam_pinfo *pinfo);
static __inline void cam_init_pinfo(cam_pinfo *pinfo)
{
pinfo->priority = CAM_PRIORITY_NONE;
pinfo->index = CAM_UNQUEUED_INDEX;
}
#endif
#endif /* _CAM_CAM_H */

1193
freebsd/cam/cam_ccb.h Normal file

File diff suppressed because it is too large Load Diff

87
freebsd/cam/cam_debug.h Normal file
View File

@@ -0,0 +1,87 @@
/*-
* Macros for tracing/loging information in the CAM layer
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_DEBUG_H
#define _CAM_CAM_DEBUG_H 1
/*
* Debugging flags.
*/
typedef enum {
CAM_DEBUG_NONE = 0x00, /* no debugging */
CAM_DEBUG_INFO = 0x01, /* scsi commands, errors, data */
CAM_DEBUG_TRACE = 0x02, /* routine flow tracking */
CAM_DEBUG_SUBTRACE = 0x04, /* internal to routine flows */
CAM_DEBUG_CDB = 0x08, /* print out SCSI CDBs only */
CAM_DEBUG_XPT = 0x10, /* print out xpt scheduling */
CAM_DEBUG_PERIPH = 0x20 /* print out peripheral calls */
} cam_debug_flags;
#if defined(CAMDEBUG) && defined(_KERNEL)
/* Path we want to debug */
extern struct cam_path *cam_dpath;
/* Current debug levels set */
extern u_int32_t cam_dflags;
/* Printf delay value (to prevent scrolling) */
extern u_int32_t cam_debug_delay;
/* Debugging macros. */
#define CAM_DEBUGGED(path, flag) \
((cam_dflags & (flag)) \
&& (cam_dpath != NULL) \
&& (xpt_path_comp(cam_dpath, path) >= 0) \
&& (xpt_path_comp(cam_dpath, path) < 2))
#define CAM_DEBUG(path, flag, printfargs) \
if ((cam_dflags & (flag)) \
&& (cam_dpath != NULL) \
&& (xpt_path_comp(cam_dpath, path) >= 0) \
&& (xpt_path_comp(cam_dpath, path) < 2)) { \
xpt_print_path(path); \
printf printfargs; \
if (cam_debug_delay != 0) \
DELAY(cam_debug_delay); \
}
#define CAM_DEBUG_PRINT(flag, printfargs) \
if (cam_dflags & (flag)) { \
printf("cam_debug: "); \
printf printfargs; \
if (cam_debug_delay != 0) \
DELAY(cam_debug_delay); \
}
#else /* !CAMDEBUG || !_KERNEL */
#define CAM_DEBUGGED(A, B) 0
#define CAM_DEBUG(A, B, C)
#define CAM_DEBUG_PRINT(A, B)
#endif /* CAMDEBUG && _KERNEL */
#endif /* _CAM_CAM_DEBUG_H */

204
freebsd/cam/cam_periph.h Normal file
View File

@@ -0,0 +1,204 @@
/*-
* Data structures and definitions for CAM peripheral ("type") drivers.
*
* Copyright (c) 1997, 1998 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_PERIPH_H
#define _CAM_CAM_PERIPH_H 1
#include <rtems/freebsd/sys/queue.h>
#include <rtems/freebsd/cam/cam_sim.h>
#ifdef _KERNEL
struct devstat;
extern struct cam_periph *xpt_periph;
extern struct periph_driver **periph_drivers;
void periphdriver_register(void *);
void periphdriver_init(int level);
#include <rtems/freebsd/sys/module.h>
#define PERIPHDRIVER_DECLARE(name, driver) \
static int name ## _modevent(module_t mod, int type, void *data) \
{ \
switch (type) { \
case MOD_LOAD: \
periphdriver_register(data); \
break; \
case MOD_UNLOAD: \
printf(#name " module unload - not possible for this module type\n"); \
return EINVAL; \
default: \
return EOPNOTSUPP; \
} \
return 0; \
} \
static moduledata_t name ## _mod = { \
#name, \
name ## _modevent, \
(void *)&driver \
}; \
DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_ANY); \
MODULE_DEPEND(name, cam, 1, 1, 1)
typedef void (periph_init_t)(void); /*
* Callback informing the peripheral driver
* it can perform it's initialization since
* the XPT is now fully initialized.
*/
typedef periph_init_t *periph_init_func_t;
struct periph_driver {
periph_init_func_t init;
char *driver_name;
TAILQ_HEAD(,cam_periph) units;
u_int generation;
u_int flags;
#define CAM_PERIPH_DRV_EARLY 0x01
};
typedef enum {
CAM_PERIPH_BIO
} cam_periph_type;
/* Generically usefull offsets into the peripheral private area */
#define ppriv_ptr0 periph_priv.entries[0].ptr
#define ppriv_ptr1 periph_priv.entries[1].ptr
#define ppriv_field0 periph_priv.entries[0].field
#define ppriv_field1 periph_priv.entries[1].field
typedef void periph_start_t (struct cam_periph *periph,
union ccb *start_ccb);
typedef cam_status periph_ctor_t (struct cam_periph *periph,
void *arg);
typedef void periph_oninv_t (struct cam_periph *periph);
typedef void periph_dtor_t (struct cam_periph *periph);
struct cam_periph {
cam_pinfo pinfo;
periph_start_t *periph_start;
periph_oninv_t *periph_oninval;
periph_dtor_t *periph_dtor;
char *periph_name;
struct cam_path *path; /* Compiled path to device */
void *softc;
struct cam_sim *sim;
u_int32_t unit_number;
cam_periph_type type;
u_int32_t flags;
#define CAM_PERIPH_RUNNING 0x01
#define CAM_PERIPH_LOCKED 0x02
#define CAM_PERIPH_LOCK_WANTED 0x04
#define CAM_PERIPH_INVALID 0x08
#define CAM_PERIPH_NEW_DEV_FOUND 0x10
#define CAM_PERIPH_RECOVERY_INPROG 0x20
#define CAM_PERIPH_SENSE_INPROG 0x40
u_int32_t immediate_priority;
u_int32_t refcount;
SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */
SLIST_ENTRY(cam_periph) periph_links;
TAILQ_ENTRY(cam_periph) unit_links;
ac_callback_t *deferred_callback;
ac_code deferred_ac;
};
#define CAM_PERIPH_MAXMAPS 2
struct cam_periph_map_info {
int num_bufs_used;
struct buf *bp[CAM_PERIPH_MAXMAPS];
};
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor,
periph_oninv_t *periph_oninvalidate,
periph_dtor_t *periph_dtor,
periph_start_t *periph_start,
char *name, cam_periph_type type, struct cam_path *,
ac_callback_t *, ac_code, void *arg);
struct cam_periph *cam_periph_find(struct cam_path *path, char *name);
cam_status cam_periph_acquire(struct cam_periph *periph);
void cam_periph_release(struct cam_periph *periph);
void cam_periph_release_locked(struct cam_periph *periph);
int cam_periph_hold(struct cam_periph *periph, int priority);
void cam_periph_unhold(struct cam_periph *periph);
void cam_periph_invalidate(struct cam_periph *periph);
int cam_periph_mapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
void cam_periph_unmapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
union ccb *cam_periph_getccb(struct cam_periph *periph,
u_int32_t priority);
void cam_periph_ccbwait(union ccb *ccb);
int cam_periph_runccb(union ccb *ccb,
int (*error_routine)(union ccb *ccb,
cam_flags camflags,
u_int32_t sense_flags),
cam_flags camflags, u_int32_t sense_flags,
struct devstat *ds);
int cam_periph_ioctl(struct cam_periph *periph, u_long cmd,
caddr_t addr,
int (*error_routine)(union ccb *ccb,
cam_flags camflags,
u_int32_t sense_flags));
void cam_freeze_devq(struct cam_path *path);
void cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags,
uint32_t arg);
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
u_int32_t opening_reduction, u_int32_t arg,
int getcount_only);
void cam_periph_async(struct cam_periph *periph, u_int32_t code,
struct cam_path *path, void *arg);
void cam_periph_bus_settle(struct cam_periph *periph,
u_int bus_settle_ms);
void cam_periph_freeze_after_event(struct cam_periph *periph,
struct timeval* event_time,
u_int duration_ms);
int cam_periph_error(union ccb *ccb, cam_flags camflags,
u_int32_t sense_flags, union ccb *save_ccb);
static __inline void
cam_periph_lock(struct cam_periph *periph)
{
mtx_lock(periph->sim->mtx);
}
static __inline void
cam_periph_unlock(struct cam_periph *periph)
{
mtx_unlock(periph->sim->mtx);
}
static __inline int
cam_periph_owned(struct cam_periph *periph)
{
return (mtx_owned(periph->sim->mtx));
}
#endif /* _KERNEL */
#endif /* _CAM_CAM_PERIPH_H */

1
freebsd/cam/cam_queue.h Normal file
View File

@@ -0,0 +1 @@
/* EMPTY */

201
freebsd/cam/cam_sim.h Normal file
View File

@@ -0,0 +1,201 @@
/*-
* Data structures and definitions for SCSI Interface Modules (SIMs).
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_SIM_H
#define _CAM_CAM_SIM_H 1
#ifdef _KERNEL
/*
* The sim driver creates a sim for each controller. The sim device
* queue is separately created in order to allow resource sharing between
* sims. For instance, a driver may create one sim for each channel of
* a multi-channel controller and use the same queue for each channel.
* In this way, the queue resources are shared across all the channels
* of the multi-channel controller.
*/
struct cam_sim;
struct cam_devq;
typedef void (*sim_action_func)(struct cam_sim *sim, union ccb *ccb);
typedef void (*sim_poll_func)(struct cam_sim *sim);
struct cam_devq * cam_simq_alloc(u_int32_t max_sim_transactions);
void cam_simq_free(struct cam_devq *devq);
struct cam_sim * cam_sim_alloc(sim_action_func sim_action,
sim_poll_func sim_poll,
const char *sim_name,
void *softc,
u_int32_t unit,
struct mtx *mtx,
int max_dev_transactions,
int max_tagged_dev_transactions,
struct cam_devq *queue);
void cam_sim_free(struct cam_sim *sim, int free_devq);
void cam_sim_hold(struct cam_sim *sim);
void cam_sim_release(struct cam_sim *sim);
/* Optional sim attributes may be set with these. */
void cam_sim_set_path(struct cam_sim *sim, u_int32_t path_id);
/* Convenience routines for accessing sim attributes. */
static __inline u_int32_t cam_sim_path(struct cam_sim *sim);
static __inline const char * cam_sim_name(struct cam_sim *sim);
static __inline void * cam_sim_softc(struct cam_sim *sim);
static __inline u_int32_t cam_sim_unit(struct cam_sim *sim);
#ifndef __rtems__
static __inline u_int32_t cam_sim_bus(struct cam_sim *sim);
#endif /* __rtems__ */
/* Generically useful offsets into the sim private area */
#define spriv_ptr0 sim_priv.entries[0].ptr
#define spriv_ptr1 sim_priv.entries[1].ptr
#define spriv_field0 sim_priv.entries[0].field
#define spriv_field1 sim_priv.entries[1].field
#ifdef __rtems__
/**
* @brief SIM states.
*
* @dot
* digraph bsd_sim_state {
* BSD_SIM_INIT -> BSD_SIM_INIT_BUSY;
* BSD_SIM_INIT -> BSD_SIM_IDLE;
* BSD_SIM_INIT_BUSY -> BSD_SIM_INIT_READY;
* BSD_SIM_BUSY -> BSD_SIM_IDLE;
* BSD_SIM_INIT_READY -> BSD_SIM_INIT;
* BSD_SIM_IDLE -> BSD_SIM_BUSY;
* BSD_SIM_IDLE -> BSD_SIM_DELETED;
* }
* @enddot
*/
enum bsd_sim_state {
BSD_SIM_INIT = 0,
BSD_SIM_INIT_BUSY,
BSD_SIM_INIT_READY,
BSD_SIM_IDLE,
BSD_SIM_BUSY,
BSD_SIM_DELETED
};
#endif /* __rtems__ */
/*
* The sim driver should not access anything directly from this
* structure.
*/
struct cam_sim {
sim_action_func sim_action;
sim_poll_func sim_poll;
const char *sim_name;
void *softc;
struct mtx *mtx;
#ifndef __rtems__
TAILQ_HEAD(, ccb_hdr) sim_doneq;
TAILQ_ENTRY(cam_sim) links;
u_int32_t path_id;/* The Boot device may set this to 0? */
#else /* __rtems__ */
char *disk;
enum bsd_sim_state state;
struct cv state_changed;
union ccb ccb;
#endif /* __rtems__ */
u_int32_t unit_number;
#ifndef __rtems__
u_int32_t bus_id;
int max_tagged_dev_openings;
int max_dev_openings;
u_int32_t flags;
#define CAM_SIM_REL_TIMEOUT_PENDING 0x01
#define CAM_SIM_MPSAFE 0x02
#define CAM_SIM_ON_DONEQ 0x04
struct callout callout;
struct cam_devq *devq; /* Device Queue to use for this SIM */
int refcount; /* References to the SIM. */
/* "Pool" of inactive ccbs managed by xpt_get_ccb and xpt_release_ccb */
SLIST_HEAD(,ccb_hdr) ccb_freeq;
/*
* Maximum size of ccb pool. Modified as devices are added/removed
* or have their * opening counts changed.
*/
u_int max_ccbs;
/* Current count of allocated ccbs */
u_int ccb_count;
#endif /* __rtems__ */
};
#define CAM_SIM_LOCK(sim) mtx_lock((sim)->mtx);
#define CAM_SIM_UNLOCK(sim) mtx_unlock((sim)->mtx);
static __inline u_int32_t
cam_sim_path(struct cam_sim *sim)
{
#ifndef __rtems__
return (sim->path_id);
#else /* __rtems__ */
return (0);
#endif /* __rtems__ */
}
static __inline const char *
cam_sim_name(struct cam_sim *sim)
{
return (sim->sim_name);
}
static __inline void *
cam_sim_softc(struct cam_sim *sim)
{
return (sim->softc);
}
static __inline u_int32_t
cam_sim_unit(struct cam_sim *sim)
{
return (sim->unit_number);
}
#ifndef __rtems__
static __inline u_int32_t
cam_sim_bus(struct cam_sim *sim)
{
return (sim->bus_id);
}
#endif /* __rtems__ */
#endif /* _KERNEL */
#endif /* _CAM_CAM_SIM_H */

138
freebsd/cam/cam_xpt.h Normal file
View File

@@ -0,0 +1,138 @@
/*-
* Data structures and definitions for dealing with the
* Common Access Method Transport (xpt) layer.
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_XPT_H
#define _CAM_CAM_XPT_H 1
/* Forward Declarations */
union ccb;
struct cam_periph;
struct cam_sim;
/*
* Definition of a CAM path. Paths are created from bus, target, and lun ids
* via xpt_create_path and allow for reference to devices without recurring
* lookups in the edt.
*/
struct cam_path;
/* Path functions */
#ifdef _KERNEL
/*
* Definition of an async handler callback block. These are used to add
* SIMs and peripherals to the async callback lists.
*/
struct async_node {
SLIST_ENTRY(async_node) links;
u_int32_t event_enable; /* Async Event enables */
void (*callback)(void *arg, u_int32_t code,
struct cam_path *path, void *args);
void *callback_arg;
};
SLIST_HEAD(async_list, async_node);
SLIST_HEAD(periph_list, cam_periph);
#if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
#error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS"
#endif
/*
* In order to enable the CAM_DEBUG_* options, the user must have CAMDEBUG
* enabled. Also, the user must have either none, or all of CAM_DEBUG_BUS,
* CAM_DEBUG_TARGET, and CAM_DEBUG_LUN specified.
*/
#if defined(CAM_DEBUG_BUS) || defined(CAM_DEBUG_TARGET) \
|| defined(CAM_DEBUG_LUN)
#ifdef CAMDEBUG
#if !defined(CAM_DEBUG_BUS) || !defined(CAM_DEBUG_TARGET) \
|| !defined(CAM_DEBUG_LUN)
#error "You must define all or none of CAM_DEBUG_BUS, CAM_DEBUG_TARGET \
and CAM_DEBUG_LUN"
#endif /* !CAM_DEBUG_BUS || !CAM_DEBUG_TARGET || !CAM_DEBUG_LUN */
#else /* !CAMDEBUG */
#error "You must use options CAMDEBUG if you use the CAM_DEBUG_* options"
#endif /* CAMDEBUG */
#endif /* CAM_DEBUG_BUS || CAM_DEBUG_TARGET || CAM_DEBUG_LUN */
void xpt_action(union ccb *new_ccb);
void xpt_action_default(union ccb *new_ccb);
union ccb *xpt_alloc_ccb(void);
union ccb *xpt_alloc_ccb_nowait(void);
void xpt_free_ccb(union ccb *free_ccb);
void xpt_setup_ccb(struct ccb_hdr *ccb_h,
struct cam_path *path,
u_int32_t priority);
void xpt_merge_ccb(union ccb *master_ccb,
union ccb *slave_ccb);
cam_status xpt_create_path(struct cam_path **new_path_ptr,
struct cam_periph *perph,
path_id_t path_id,
target_id_t target_id, lun_id_t lun_id);
cam_status xpt_create_path_unlocked(struct cam_path **new_path_ptr,
struct cam_periph *perph,
path_id_t path_id,
target_id_t target_id, lun_id_t lun_id);
void xpt_free_path(struct cam_path *path);
int xpt_path_comp(struct cam_path *path1,
struct cam_path *path2);
void xpt_print_path(struct cam_path *path);
void xpt_print(struct cam_path *path, const char *fmt, ...);
int xpt_path_string(struct cam_path *path, char *str,
size_t str_len);
path_id_t xpt_path_path_id(struct cam_path *path);
target_id_t xpt_path_target_id(struct cam_path *path);
lun_id_t xpt_path_lun_id(struct cam_path *path);
struct cam_sim *xpt_path_sim(struct cam_path *path);
struct cam_periph *xpt_path_periph(struct cam_path *path);
void xpt_async(u_int32_t async_code, struct cam_path *path,
void *async_arg);
void xpt_rescan(union ccb *ccb);
void xpt_hold_boot(void);
void xpt_release_boot(void);
void xpt_lock_buses(void);
void xpt_unlock_buses(void);
cam_status xpt_register_async(int event, ac_callback_t *cbfunc,
void *cbarg, struct cam_path *path);
cam_status xpt_compile_path(struct cam_path *new_path,
struct cam_periph *perph,
path_id_t path_id,
target_id_t target_id,
lun_id_t lun_id);
void xpt_release_path(struct cam_path *path);
#endif /* _KERNEL */
#endif /* _CAM_CAM_XPT_H */

57
freebsd/cam/cam_xpt_sim.h Normal file
View File

@@ -0,0 +1,57 @@
/*-
* Data structures and definitions for dealing with the
* Common Access Method Transport (xpt) layer.
*
* Copyright (c) 1997 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAM_CAM_XPT_SIM_H
#define _CAM_CAM_XPT_SIM_H 1
#include <rtems/freebsd/cam/cam_xpt.h>
#include <rtems/freebsd/cam/cam_queue.h>
/* Functions accessed by SIM drivers */
#ifdef _KERNEL
int32_t xpt_bus_register(struct cam_sim *sim, device_t parent,
u_int32_t bus);
int32_t xpt_bus_deregister(path_id_t path_id);
u_int32_t xpt_freeze_simq(struct cam_sim *sim, u_int count);
void xpt_release_simq(struct cam_sim *sim, int run_queue);
u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count);
u_int32_t xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl,
u_int count);
void xpt_release_devq(struct cam_path *path,
u_int count, int run_queue);
void xpt_release_devq_rl(struct cam_path *path, cam_rl rl,
u_int count, int run_queue);
int xpt_sim_opened(struct cam_sim *sim);
void xpt_done(union ccb *done_ccb);
#endif
#endif /* _CAM_CAM_XPT_SIM_H */

4305
freebsd/cam/scsi/scsi_all.c Normal file

File diff suppressed because it is too large Load Diff

1454
freebsd/cam/scsi/scsi_all.h Normal file

File diff suppressed because it is too large Load Diff

463
freebsd/cam/scsi/scsi_da.h Normal file
View File

@@ -0,0 +1,463 @@
/*
* Structures and definitions for SCSI commands to Direct Access Devices
*/
/*-
* Some lines of this file come from a file of the name "scsi.h"
* distributed by OSF as part of mach2.5,
* so the following disclaimer has been kept.
*
* Copyright 1990 by Open Software Foundation,
* Grenoble, FRANCE
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation, and that the name of OSF or Open Software
* Foundation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission.
*
* OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*-
* Largely written by Julian Elischer (julian@tfs.com)
* for TRW Financial Systems.
*
* TRW Financial Systems, in accordance with their agreement with Carnegie
* Mellon University, makes this software available to CMU to distribute
* or use in any manner that they see fit as long as this message is kept with
* the software. For this reason TFS also grants any other persons or
* organisations permission to use or modify this software.
*
* TFS supplies this software to be publicly redistributed
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $FreeBSD$
*/
#ifndef _SCSI_SCSI_DA_H
#define _SCSI_SCSI_DA_H 1
#include <rtems/freebsd/sys/cdefs.h>
struct scsi_rezero_unit
{
u_int8_t opcode;
#define SRZU_LUN_MASK 0xE0
u_int8_t byte2;
u_int8_t reserved[3];
u_int8_t control;
};
/*
* NOTE: The lower three bits of byte2 of the format CDB are the same as
* the lower three bits of byte2 of the read defect data CDB, below.
*/
struct scsi_format_unit
{
u_int8_t opcode;
u_int8_t byte2;
#define FU_FORMAT_MASK SRDD10_DLIST_FORMAT_MASK
#define FU_BLOCK_FORMAT SRDD10_BLOCK_FORMAT
#define FU_BFI_FORMAT SRDD10_BYTES_FROM_INDEX_FORMAT
#define FU_PHYS_FORMAT SRDD10_PHYSICAL_SECTOR_FORMAT
#define FU_CMPLST 0x08
#define FU_FMT_DATA 0x10
u_int8_t vendor_specific;
u_int8_t interleave[2];
u_int8_t control;
};
struct scsi_reassign_blocks
{
u_int8_t opcode;
u_int8_t byte2;
u_int8_t unused[3];
u_int8_t control;
};
struct scsi_read_defect_data_10
{
u_int8_t opcode;
/*
* The most significant 3 bits are the LUN, the other 5 are
* reserved.
*/
#define SRDD10_LUN_MASK 0xE0
u_int8_t byte2;
#define SRDD10_GLIST 0x08
#define SRDD10_PLIST 0x10
#define SRDD10_DLIST_FORMAT_MASK 0x07
#define SRDD10_BLOCK_FORMAT 0x00
#define SRDD10_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDD10_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t reserved[4];
u_int8_t alloc_length[2];
u_int8_t control;
};
struct scsi_read_defect_data_12
{
u_int8_t opcode;
/*
* The most significant 3 bits are the LUN, the other 5 are
* reserved.
*/
#define SRDD12_LUN_MASK 0xE0
u_int8_t byte2;
#define SRDD12_GLIST 0x08
#define SRDD12_PLIST 0x10
#define SRDD12_DLIST_FORMAT_MASK 0x07
#define SRDD12_BLOCK_FORMAT 0x00
#define SRDD12_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDD12_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t reserved[4];
u_int8_t alloc_length[4];
u_int8_t control;
};
/*
* Opcodes
*/
#define REZERO_UNIT 0x01
#define FORMAT_UNIT 0x04
#define REASSIGN_BLOCKS 0x07
#define MODE_SELECT 0x15
#define MODE_SENSE 0x1a
#define READ_FORMAT_CAPACITIES 0x23
#define WRITE_AND_VERIFY 0x2e
#define VERIFY 0x2f
#define READ_DEFECT_DATA_10 0x37
#define READ_DEFECT_DATA_12 0xb7
struct format_defect_list_header
{
u_int8_t reserved;
u_int8_t byte2;
#define FU_DLH_VS 0x01
#define FU_DLH_IMMED 0x02
#define FU_DLH_DSP 0x04
#define FU_DLH_IP 0x08
#define FU_DLH_STPF 0x10
#define FU_DLH_DCRT 0x20
#define FU_DLH_DPRY 0x40
#define FU_DLH_FOV 0x80
u_int8_t defect_list_length[2];
};
struct format_ipat_descriptor
{
u_int8_t byte1;
#define FU_INIT_NO_HDR 0x00
#define FU_INIT_LBA_MSB 0x40
#define FU_INIT_LBA_EACH 0x80
#define FU_INIT_SI 0x20
u_int8_t pattern_type;
#define FU_INIT_PAT_DEFAULT 0x00
#define FU_INIT_PAT_REPEAT 0x01
u_int8_t pat_length[2];
};
struct scsi_read_format_capacities
{
uint8_t opcode; /* READ_FORMAT_CAPACITIES */
uint8_t byte2;
#define SRFC_LUN_MASK 0xE0
uint8_t reserved0[5];
uint8_t alloc_length[2];
uint8_t reserved1[3];
};
struct scsi_verify
{
uint8_t opcode; /* VERIFY */
uint8_t byte2;
#define SVFY_LUN_MASK 0xE0
#define SVFY_RELADR 0x01
#define SVFY_BYTECHK 0x02
#define SVFY_DPO 0x10
uint8_t addr[4]; /* LBA to begin verification at */
uint8_t reserved0[1];
uint8_t len[2]; /* number of blocks to verify */
uint8_t reserved1[3];
};
struct scsi_write_and_verify
{
uint8_t opcode; /* WRITE_AND_VERIFY */
uint8_t byte2;
#define SWVY_LUN_MASK 0xE0
#define SWVY_RELADR 0x01
#define SWVY_BYTECHK 0x02
#define SWVY_DPO 0x10
uint8_t addr[4]; /* LBA to begin verification at */
uint8_t reserved0[1];
uint8_t len[2]; /* number of blocks to write and verify */
uint8_t reserved1[3];
};
/*
* Replies to READ_FORMAT_CAPACITIES look like this:
*
* struct format_capacity_list_header
* struct format_capacity_descriptor[1..n]
*
* These are similar, but not totally identical to, the
* defect list used to format a rigid disk.
*
* The appropriate csio_decode() format string looks like this:
* "{} *i3 {Len} i1 {Blocks} i4 {} *b6 {Code} b2 {Blocklen} i3"
*
* If the capacity_list_length is greater than
* sizeof(struct format_capacity_descriptor), then there are
* additional format capacity descriptors available which
* denote which format(s) the drive can handle.
*
* (Source: USB Mass Storage UFI Specification)
*/
struct format_capacity_list_header {
uint8_t unused[3];
uint8_t capacity_list_length;
};
struct format_capacity_descriptor {
uint8_t nblocks[4]; /* total number of LBAs */
uint8_t byte4; /* only present in max/cur descriptor */
#define FCD_CODE_MASK 0x03 /* mask for code field above */
#define FCD_UNFORMATTED 0x01 /* unformatted media present,
* maximum capacity returned */
#define FCD_FORMATTED 0x02 /* formatted media present,
* current capacity returned */
#define FCD_NOMEDIA 0x03 /* no media present,
* maximum device capacity returned */
uint8_t block_length[3]; /* length of an LBA in bytes */
};
struct scsi_reassign_blocks_data
{
u_int8_t reserved[2];
u_int8_t length[2];
struct {
u_int8_t dlbaddr[4]; /* defect logical block address */
} defect_descriptor[1];
};
/*
* This is the list header for the READ DEFECT DATA(10) command above.
* It may be a bit wrong to append the 10 at the end of the data structure,
* since it's only 4 bytes but it does tie it to the 10 byte command.
*/
struct scsi_read_defect_data_hdr_10
{
u_int8_t reserved;
#define SRDDH10_GLIST 0x08
#define SRDDH10_PLIST 0x10
#define SRDDH10_DLIST_FORMAT_MASK 0x07
#define SRDDH10_BLOCK_FORMAT 0x00
#define SRDDH10_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDDH10_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t length[2];
};
struct scsi_defect_desc_block
{
u_int8_t address[4];
};
struct scsi_defect_desc_bytes_from_index
{
u_int8_t cylinder[3];
u_int8_t head;
u_int8_t bytes_from_index[4];
};
struct scsi_defect_desc_phys_sector
{
u_int8_t cylinder[3];
u_int8_t head;
u_int8_t sector[4];
};
struct scsi_read_defect_data_hdr_12
{
u_int8_t reserved;
#define SRDDH12_GLIST 0x08
#define SRDDH12_PLIST 0x10
#define SRDDH12_DLIST_FORMAT_MASK 0x07
#define SRDDH12_BLOCK_FORMAT 0x00
#define SRDDH12_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDDH12_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t length[4];
};
union disk_pages /* this is the structure copied from osf */
{
struct format_device_page {
u_int8_t pg_code; /* page code (should be 3) */
#define SMS_FORMAT_DEVICE_PAGE 0x03 /* only 6 bits valid */
u_int8_t pg_length; /* page length (should be 0x16) */
#define SMS_FORMAT_DEVICE_PLEN 0x16
u_int8_t trk_z_1; /* tracks per zone (MSB) */
u_int8_t trk_z_0; /* tracks per zone (LSB) */
u_int8_t alt_sec_1; /* alternate sectors per zone (MSB) */
u_int8_t alt_sec_0; /* alternate sectors per zone (LSB) */
u_int8_t alt_trk_z_1; /* alternate tracks per zone (MSB) */
u_int8_t alt_trk_z_0; /* alternate tracks per zone (LSB) */
u_int8_t alt_trk_v_1; /* alternate tracks per volume (MSB) */
u_int8_t alt_trk_v_0; /* alternate tracks per volume (LSB) */
u_int8_t ph_sec_t_1; /* physical sectors per track (MSB) */
u_int8_t ph_sec_t_0; /* physical sectors per track (LSB) */
u_int8_t bytes_s_1; /* bytes per sector (MSB) */
u_int8_t bytes_s_0; /* bytes per sector (LSB) */
u_int8_t interleave_1; /* interleave (MSB) */
u_int8_t interleave_0; /* interleave (LSB) */
u_int8_t trk_skew_1; /* track skew factor (MSB) */
u_int8_t trk_skew_0; /* track skew factor (LSB) */
u_int8_t cyl_skew_1; /* cylinder skew (MSB) */
u_int8_t cyl_skew_0; /* cylinder skew (LSB) */
u_int8_t flags; /* various */
#define DISK_FMT_SURF 0x10
#define DISK_FMT_RMB 0x20
#define DISK_FMT_HSEC 0x40
#define DISK_FMT_SSEC 0x80
u_int8_t reserved21;
u_int8_t reserved22;
u_int8_t reserved23;
} format_device;
struct rigid_geometry_page {
u_int8_t pg_code; /* page code (should be 4) */
#define SMS_RIGID_GEOMETRY_PAGE 0x04
u_int8_t pg_length; /* page length (should be 0x16) */
#define SMS_RIGID_GEOMETRY_PLEN 0x16
u_int8_t ncyl_2; /* number of cylinders (MSB) */
u_int8_t ncyl_1; /* number of cylinders */
u_int8_t ncyl_0; /* number of cylinders (LSB) */
u_int8_t nheads; /* number of heads */
u_int8_t st_cyl_wp_2; /* starting cyl., write precomp (MSB) */
u_int8_t st_cyl_wp_1; /* starting cyl., write precomp */
u_int8_t st_cyl_wp_0; /* starting cyl., write precomp (LSB) */
u_int8_t st_cyl_rwc_2; /* starting cyl., red. write cur (MSB)*/
u_int8_t st_cyl_rwc_1; /* starting cyl., red. write cur */
u_int8_t st_cyl_rwc_0; /* starting cyl., red. write cur (LSB)*/
u_int8_t driv_step_1; /* drive step rate (MSB) */
u_int8_t driv_step_0; /* drive step rate (LSB) */
u_int8_t land_zone_2; /* landing zone cylinder (MSB) */
u_int8_t land_zone_1; /* landing zone cylinder */
u_int8_t land_zone_0; /* landing zone cylinder (LSB) */
u_int8_t rpl; /* rotational position locking (2 bits) */
u_int8_t rot_offset; /* rotational offset */
u_int8_t reserved19;
u_int8_t medium_rot_rate_1; /* medium rotation rate (RPM) (MSB) */
u_int8_t medium_rot_rate_0; /* medium rotation rate (RPM) (LSB) */
u_int8_t reserved22;
u_int8_t reserved23;
} rigid_geometry;
struct flexible_disk_page {
u_int8_t pg_code; /* page code (should be 5) */
#define SMS_FLEXIBLE_GEOMETRY_PAGE 0x05
u_int8_t pg_length; /* page length (should be 0x1E) */
#define SMS_FLEXIBLE_GEOMETRY_PLEN 0x1E
u_int8_t xfr_rate_1; /* transfer rate (MSB) */
u_int8_t xfr_rate_0; /* transfer rate (LSB) */
u_int8_t nheads; /* number of heads */
u_int8_t sec_per_track; /* Sectors per track */
u_int8_t bytes_s_1; /* bytes per sector (MSB) */
u_int8_t bytes_s_0; /* bytes per sector (LSB) */
u_int8_t ncyl_1; /* number of cylinders (MSB) */
u_int8_t ncyl_0; /* number of cylinders (LSB) */
u_int8_t st_cyl_wp_1; /* starting cyl., write precomp (MSB) */
u_int8_t st_cyl_wp_0; /* starting cyl., write precomp (LSB) */
u_int8_t st_cyl_rwc_1; /* starting cyl., red. write cur (MSB)*/
u_int8_t st_cyl_rwc_0; /* starting cyl., red. write cur (LSB)*/
u_int8_t driv_step_1; /* drive step rate (MSB) */
u_int8_t driv_step_0; /* drive step rate (LSB) */
u_int8_t driv_step_pw; /* drive step pulse width */
u_int8_t head_stl_del_1;/* Head settle delay (MSB) */
u_int8_t head_stl_del_0;/* Head settle delay (LSB) */
u_int8_t motor_on_del; /* Motor on delay */
u_int8_t motor_off_del; /* Motor off delay */
u_int8_t trdy_ssn_mo; /* XXX ??? */
u_int8_t spc; /* XXX ??? */
u_int8_t write_comp; /* Write compensation */
u_int8_t head_load_del; /* Head load delay */
u_int8_t head_uload_del;/* Head un-load delay */
u_int8_t pin32_pin2;
u_int8_t pin4_pint1;
u_int8_t medium_rot_rate_1; /* medium rotation rate (RPM) (MSB) */
u_int8_t medium_rot_rate_0; /* medium rotation rate (RPM) (LSB) */
u_int8_t reserved30;
u_int8_t reserved31;
} flexible_disk;
};
struct scsi_da_rw_recovery_page {
u_int8_t page_code;
#define SMS_RW_ERROR_RECOVERY_PAGE 0x01
u_int8_t page_length;
u_int8_t byte3;
#define SMS_RWER_AWRE 0x80
#define SMS_RWER_ARRE 0x40
#define SMS_RWER_TB 0x20
#define SMS_RWER_RC 0x10
#define SMS_RWER_EER 0x08
#define SMS_RWER_PER 0x04
#define SMS_RWER_DTE 0x02
#define SMS_RWER_DCR 0x01
u_int8_t read_retry_count;
u_int8_t correction_span;
u_int8_t head_offset_count;
u_int8_t data_strobe_offset_cnt;
u_int8_t reserved;
u_int8_t write_retry_count;
u_int8_t reserved2;
u_int8_t recovery_time_limit[2];
};
__BEGIN_DECLS
/*
* XXX This is only left out of the kernel build to silence warnings. If,
* for some reason this function is used in the kernel, the ifdefs should
* be moved so it is included both in the kernel and userland.
*/
#ifndef _KERNEL
void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
u_int8_t *data_ptr, u_int32_t dxfer_len,
u_int8_t sense_len, u_int32_t timeout);
#endif /* !_KERNEL */
__END_DECLS
#endif /* _SCSI_SCSI_DA_H */