Widen lun_id_t to 64 bits. This is a follow-on to r257345 to let the kernel
support all valid SAM-5 LUN IDs. CAM_VERSION is bumped, as the CAM ABI (though not API) is changed. No behavior is changed relative to r257345 except that LUNs with non-zero high 32 bits will no longer be ignored during device enumeration for SIMs that have set PIM_EXTLUNS. Reviewed by: scottl
This commit is contained in:
parent
c4ffb19933
commit
f9ad7a0406
@ -39,16 +39,12 @@
|
||||
|
||||
typedef u_int path_id_t;
|
||||
typedef u_int target_id_t;
|
||||
typedef u_int lun_id_t;
|
||||
typedef union {
|
||||
u_int64_t lun64;
|
||||
u_int8_t lun[8];
|
||||
} lun64_id_t;
|
||||
typedef u_int64_t 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)
|
||||
#define CAM_LUN_WILDCARD (~(u_int)0)
|
||||
|
||||
#define CAM_EXTLUN_BYTE_SWIZZLE(lun) ( \
|
||||
((((u_int64_t)lun) & 0xffff000000000000L) >> 48) | \
|
||||
|
@ -109,10 +109,6 @@ typedef enum {
|
||||
CAM_UNLOCKED = 0x80000000 /* Call callback without lock. */
|
||||
} ccb_flags;
|
||||
|
||||
typedef enum {
|
||||
CAM_EXTLUN_VALID = 0x00000001,/* 64bit lun field is valid */
|
||||
} ccb_xflags;
|
||||
|
||||
/* XPT Opcodes for xpt_action */
|
||||
typedef enum {
|
||||
/* Function code flags are bits greater than 0xff */
|
||||
@ -326,7 +322,6 @@ struct ccb_hdr {
|
||||
path_id_t path_id; /* Path ID for the request */
|
||||
target_id_t target_id; /* Target device ID */
|
||||
lun_id_t target_lun; /* Target LUN number */
|
||||
lun64_id_t ext_lun; /* 64bit extended/multi-level LUNs */
|
||||
u_int32_t flags; /* ccb_flags */
|
||||
u_int32_t xflags; /* Extended flags */
|
||||
ccb_ppriv_area periph_priv;
|
||||
@ -555,7 +550,7 @@ struct ccb_dev_match {
|
||||
/*
|
||||
* Definitions for the path inquiry CCB fields.
|
||||
*/
|
||||
#define CAM_VERSION 0x18 /* Hex value for current version */
|
||||
#define CAM_VERSION 0x19 /* Hex value for current version */
|
||||
|
||||
typedef enum {
|
||||
PI_MDP_ABLE = 0x80, /* Supports MDP message */
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <cam/cam_ccb.h>
|
||||
#include <cam/cam_xpt.h>
|
||||
#include <cam/cam_compat.h>
|
||||
#include <cam/cam_periph.h>
|
||||
|
||||
#include <cam/scsi/scsi_pass.h>
|
||||
|
||||
@ -53,6 +54,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
|
||||
int flag, struct thread *td, d_ioctl_t *cbfnp);
|
||||
static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr,
|
||||
int flag, struct thread *td, d_ioctl_t *cbfnp);
|
||||
static int cam_compat_translate_dev_match_0x18(union ccb *ccb);
|
||||
|
||||
int
|
||||
cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
@ -63,28 +67,28 @@ cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
switch (cmd) {
|
||||
case CAMIOCOMMAND_0x16:
|
||||
{
|
||||
union ccb *ccb;
|
||||
struct ccb_hdr_0x17 *hdr17;
|
||||
|
||||
ccb = (union ccb *)addr;
|
||||
if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) {
|
||||
ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16;
|
||||
ccb->ccb_h.flags |= CAM_DATA_SG_PADDR;
|
||||
hdr17 = (struct ccb_hdr_0x17 *)addr;
|
||||
if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) {
|
||||
hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16;
|
||||
hdr17->flags |= CAM_DATA_SG_PADDR;
|
||||
}
|
||||
if (ccb->ccb_h.flags & CAM_DATA_PHYS_0x16) {
|
||||
ccb->ccb_h.flags &= ~CAM_DATA_PHYS_0x16;
|
||||
ccb->ccb_h.flags |= CAM_DATA_PADDR;
|
||||
if (hdr17->flags & CAM_DATA_PHYS_0x16) {
|
||||
hdr17->flags &= ~CAM_DATA_PHYS_0x16;
|
||||
hdr17->flags |= CAM_DATA_PADDR;
|
||||
}
|
||||
if (ccb->ccb_h.flags & CAM_SCATTER_VALID_0x16) {
|
||||
ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16;
|
||||
ccb->ccb_h.flags |= CAM_DATA_SG;
|
||||
if (hdr17->flags & CAM_SCATTER_VALID_0x16) {
|
||||
hdr17->flags &= CAM_SCATTER_VALID_0x16;
|
||||
hdr17->flags |= CAM_DATA_SG;
|
||||
}
|
||||
cmd = CAMIOCOMMAND;
|
||||
error = (cbfnp)(dev, cmd, addr, flag, td);
|
||||
error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
|
||||
break;
|
||||
}
|
||||
case CAMGETPASSTHRU_0x16:
|
||||
cmd = CAMGETPASSTHRU;
|
||||
error = (cbfnp)(dev, cmd, addr, flag, td);
|
||||
error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
|
||||
break;
|
||||
case CAMIOCOMMAND_0x17:
|
||||
cmd = CAMIOCOMMAND;
|
||||
@ -94,6 +98,14 @@ cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
cmd = CAMGETPASSTHRU;
|
||||
error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
|
||||
break;
|
||||
case CAMIOCOMMAND_0x18:
|
||||
cmd = CAMIOCOMMAND;
|
||||
error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
|
||||
break;
|
||||
case CAMGETPASSTHRU_0x18:
|
||||
cmd = CAMGETPASSTHRU;
|
||||
error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
|
||||
break;
|
||||
default:
|
||||
error = ENOTTY;
|
||||
}
|
||||
@ -127,7 +139,6 @@ cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
hdr->path_id = hdr17->path_id;
|
||||
hdr->target_id = hdr17->target_id;
|
||||
hdr->target_lun = hdr17->target_lun;
|
||||
hdr->ext_lun.lun64 = 0;
|
||||
hdr->flags = hdr17->flags;
|
||||
hdr->xflags = 0;
|
||||
hdr->periph_priv = hdr17->periph_priv;
|
||||
@ -159,13 +170,11 @@ cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
hdr17->sim_priv = hdr->sim_priv;
|
||||
hdr17->timeout = hdr->timeout;
|
||||
|
||||
/* The PATH_INQ only needs special handling on the way out */
|
||||
if (ccb->ccb_h.func_code != XPT_PATH_INQ) {
|
||||
bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
|
||||
} else {
|
||||
if (ccb->ccb_h.func_code == XPT_PATH_INQ) {
|
||||
struct ccb_pathinq *cpi;
|
||||
struct ccb_pathinq_0x17 *cpi17;
|
||||
|
||||
/* The PATH_INQ only needs special handling on the way out */
|
||||
cpi = &ccb->cpi;
|
||||
cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
|
||||
cpi17->version_num = cpi->version_num;
|
||||
@ -196,9 +205,151 @@ cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
cpi17->hba_device = cpi->hba_device;
|
||||
cpi17->hba_subvendor = cpi->hba_subvendor;
|
||||
cpi17->hba_subdevice = cpi->hba_subdevice;
|
||||
} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
|
||||
/* Copy the rest of the header over */
|
||||
bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
|
||||
|
||||
cam_compat_translate_dev_match_0x18(ccb);
|
||||
} else {
|
||||
bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
|
||||
}
|
||||
|
||||
xpt_free_ccb(ccb);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
struct thread *td, d_ioctl_t *cbfnp)
|
||||
{
|
||||
union ccb *ccb;
|
||||
struct ccb_hdr *hdr;
|
||||
struct ccb_hdr_0x18 *hdr18;
|
||||
uint8_t *ccbb, *ccbb18;
|
||||
u_int error;
|
||||
|
||||
hdr18 = (struct ccb_hdr_0x18 *)addr;
|
||||
ccb = xpt_alloc_ccb();
|
||||
hdr = &ccb->ccb_h;
|
||||
|
||||
hdr->pinfo = hdr18->pinfo;
|
||||
hdr->xpt_links = hdr18->xpt_links;
|
||||
hdr->sim_links = hdr18->sim_links;
|
||||
hdr->periph_links = hdr18->periph_links;
|
||||
hdr->retry_count = hdr18->retry_count;
|
||||
hdr->cbfcnp = hdr18->cbfcnp;
|
||||
hdr->func_code = hdr18->func_code;
|
||||
hdr->status = hdr18->status;
|
||||
hdr->path = hdr18->path;
|
||||
hdr->path_id = hdr18->path_id;
|
||||
hdr->target_id = hdr18->target_id;
|
||||
hdr->target_lun = hdr18->target_lun;
|
||||
if (hdr18->xflags & CAM_EXTLUN_VALID_0x18)
|
||||
hdr->target_lun = hdr18->ext_lun;
|
||||
hdr->flags = hdr18->flags;
|
||||
hdr->xflags = hdr18->xflags;
|
||||
hdr->periph_priv = hdr18->periph_priv;
|
||||
hdr->sim_priv = hdr18->sim_priv;
|
||||
hdr->timeout = hdr18->timeout;
|
||||
hdr->softtimeout.tv_sec = 0;
|
||||
hdr->softtimeout.tv_usec = 0;
|
||||
|
||||
ccbb = (uint8_t *)&hdr[1];
|
||||
ccbb18 = (uint8_t *)&hdr18[1];
|
||||
bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
|
||||
|
||||
error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
|
||||
|
||||
hdr18->pinfo = hdr->pinfo;
|
||||
hdr18->xpt_links = hdr->xpt_links;
|
||||
hdr18->sim_links = hdr->sim_links;
|
||||
hdr18->periph_links = hdr->periph_links;
|
||||
hdr18->retry_count = hdr->retry_count;
|
||||
hdr18->cbfcnp = hdr->cbfcnp;
|
||||
hdr18->func_code = hdr->func_code;
|
||||
hdr18->status = hdr->status;
|
||||
hdr18->path = hdr->path;
|
||||
hdr18->path_id = hdr->path_id;
|
||||
hdr18->target_id = hdr->target_id;
|
||||
hdr18->target_lun = hdr->target_lun;
|
||||
hdr18->ext_lun = hdr->target_lun;
|
||||
hdr18->flags = hdr->flags;
|
||||
hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18;
|
||||
hdr18->periph_priv = hdr->periph_priv;
|
||||
hdr18->sim_priv = hdr->sim_priv;
|
||||
hdr18->timeout = hdr->timeout;
|
||||
|
||||
bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
|
||||
|
||||
if (ccb->ccb_h.func_code == XPT_DEV_MATCH)
|
||||
cam_compat_translate_dev_match_0x18(ccb);
|
||||
|
||||
xpt_free_ccb(ccb);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
cam_compat_translate_dev_match_0x18(union ccb *ccb)
|
||||
{
|
||||
struct dev_match_result *dm;
|
||||
struct dev_match_result_0x18 *dm18;
|
||||
struct cam_periph_map_info mapinfo;
|
||||
int i;
|
||||
|
||||
/* Remap the CCB into kernel address space */
|
||||
bzero(&mapinfo, sizeof(mapinfo));
|
||||
cam_periph_mapmem(ccb, &mapinfo);
|
||||
|
||||
dm = ccb->cdm.matches;
|
||||
/* Translate in-place: old fields are smaller */
|
||||
dm18 = (struct dev_match_result_0x18 *)(dm);
|
||||
|
||||
for (i = 0; i < ccb->cdm.num_matches; i++) {
|
||||
dm18[i].type = dm[i].type;
|
||||
switch (dm[i].type) {
|
||||
case DEV_MATCH_PERIPH:
|
||||
memcpy(&dm18[i].result.periph_result.periph_name,
|
||||
&dm[i].result.periph_result.periph_name,
|
||||
DEV_IDLEN);
|
||||
dm18[i].result.periph_result.unit_number =
|
||||
dm[i].result.periph_result.unit_number;
|
||||
dm18[i].result.periph_result.path_id =
|
||||
dm[i].result.periph_result.path_id;
|
||||
dm18[i].result.periph_result.target_id =
|
||||
dm[i].result.periph_result.target_id;
|
||||
dm18[i].result.periph_result.target_lun =
|
||||
dm[i].result.periph_result.target_lun;
|
||||
break;
|
||||
case DEV_MATCH_DEVICE:
|
||||
dm18[i].result.device_result.path_id =
|
||||
dm[i].result.device_result.path_id;
|
||||
dm18[i].result.device_result.target_id =
|
||||
dm[i].result.device_result.target_id;
|
||||
dm18[i].result.device_result.target_lun =
|
||||
dm[i].result.device_result.target_lun;
|
||||
dm18[i].result.device_result.protocol =
|
||||
dm[i].result.device_result.protocol;
|
||||
memcpy(&dm18[i].result.device_result.inq_data,
|
||||
&dm[i].result.device_result.inq_data,
|
||||
sizeof(struct scsi_inquiry_data));
|
||||
memcpy(&dm18[i].result.device_result.ident_data,
|
||||
&dm[i].result.device_result.ident_data,
|
||||
sizeof(struct ata_params));
|
||||
dm18[i].result.device_result.flags =
|
||||
dm[i].result.device_result.flags;
|
||||
break;
|
||||
case DEV_MATCH_BUS:
|
||||
memcpy(&dm18[i].result.bus_result,
|
||||
&dm[i].result.bus_result,
|
||||
sizeof(struct bus_match_result));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cam_periph_unmapmem(ccb, &mapinfo);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ struct ccb_hdr_0x17 {
|
||||
struct cam_path *path; /* Compiled path for this ccb */
|
||||
path_id_t path_id; /* Path ID for the request */
|
||||
target_id_t target_id; /* Target device ID */
|
||||
lun_id_t target_lun; /* Target LUN number */
|
||||
u_int target_lun; /* Target LUN number */
|
||||
u_int32_t flags; /* ccb_flags */
|
||||
ccb_ppriv_area periph_priv;
|
||||
ccb_spriv_area sim_priv;
|
||||
@ -116,5 +116,64 @@ struct ccb_pathinq_0x17 {
|
||||
#define CAMIOCOMMAND_0x17 _IOC(IOC_INOUT, CAM_VERSION_0x17, 2, CAM_0X17_LEN)
|
||||
#define CAMGETPASSTHRU_0x17 _IOC(IOC_INOUT, CAM_VERSION_0x17, 3, CAM_0X17_LEN)
|
||||
|
||||
/* Version 0x18 compatibility */
|
||||
#define CAM_VERSION_0x18 0x18
|
||||
|
||||
struct ccb_hdr_0x18 {
|
||||
cam_pinfo pinfo; /* Info for priority scheduling */
|
||||
camq_entry xpt_links; /* For chaining in the XPT layer */
|
||||
camq_entry sim_links; /* For chaining in the SIM layer */
|
||||
camq_entry periph_links; /* For chaining in the type driver */
|
||||
u_int32_t retry_count;
|
||||
void (*cbfcnp)(struct cam_periph *, union ccb *);
|
||||
xpt_opcode func_code; /* XPT function code */
|
||||
u_int32_t status; /* Status returned by CAM subsystem */
|
||||
struct cam_path *path; /* Compiled path for this ccb */
|
||||
path_id_t path_id; /* Path ID for the request */
|
||||
target_id_t target_id; /* Target device ID */
|
||||
u_int target_lun; /* Target LUN number */
|
||||
u_int64_t ext_lun; /* 64-bit LUN, more or less */
|
||||
u_int32_t flags; /* ccb_flags */
|
||||
u_int32_t xflags; /* extended ccb_flags */
|
||||
ccb_ppriv_area periph_priv;
|
||||
ccb_spriv_area sim_priv;
|
||||
ccb_qos_area qos;
|
||||
u_int32_t timeout; /* Hard timeout value in seconds */
|
||||
struct timeval softtimeout; /* Soft timeout value in sec + usec */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CAM_EXTLUN_VALID_0x18 = 0x00000001,/* 64bit lun field is valid */
|
||||
} ccb_xflags_0x18;
|
||||
|
||||
struct dev_match_result_0x18 {
|
||||
dev_match_type type;
|
||||
union {
|
||||
struct {
|
||||
char periph_name[DEV_IDLEN];
|
||||
u_int32_t unit_number;
|
||||
path_id_t path_id;
|
||||
target_id_t target_id;
|
||||
u_int target_lun;
|
||||
} periph_result;
|
||||
struct {
|
||||
path_id_t path_id;
|
||||
target_id_t target_id;
|
||||
u_int target_lun;
|
||||
cam_proto protocol;
|
||||
struct scsi_inquiry_data inq_data;
|
||||
struct ata_params ident_data;
|
||||
dev_result_flags flags;
|
||||
} device_result;
|
||||
struct bus_match_result bus_result;
|
||||
} result;
|
||||
};
|
||||
|
||||
#define CAM_0X18_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr) + sizeof(struct ccb_hdr_0x18))
|
||||
#define CAM_0X18_DATA_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr_0x18))
|
||||
|
||||
#define CAMIOCOMMAND_0x18 _IOC(IOC_INOUT, CAM_VERSION_0x18, 2, CAM_0X18_LEN)
|
||||
#define CAMGETPASSTHRU_0x18 _IOC(IOC_INOUT, CAM_VERSION_0x18, 3, CAM_0X18_LEN)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -101,10 +101,8 @@ SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
|
||||
(lval) |= (lp)->luns[(i)].lundata[1]; \
|
||||
}
|
||||
#define CAM_GET_LUN(lp, i, lval) \
|
||||
(lval) = scsi_4btoul((lp)->luns[(i)].lundata); \
|
||||
(lval) = ((lval) >> 16) | ((lval) << 16);
|
||||
#define CAM_LUN_ONLY_32BITS(lp, i) \
|
||||
(scsi_4btoul(&((lp)->luns[(i)].lundata[4])) == 0)
|
||||
(lval) = scsi_8btou64((lp)->luns[(i)].lundata); \
|
||||
(lval) = CAM_EXTLUN_BYTE_SWIZZLE(lval);
|
||||
|
||||
/*
|
||||
* If we're not quirked to search <= the first 8 luns
|
||||
@ -1766,8 +1764,6 @@ probe_purge_old(struct cam_path *path, struct scsi_report_luns_data *new,
|
||||
continue;
|
||||
CAM_GET_SIMPLE_LUN(old, idx1, this_lun);
|
||||
}
|
||||
if (!CAM_LUN_ONLY_32BITS(old, idx1))
|
||||
continue;
|
||||
|
||||
if (xpt_create_path(&tp, NULL, xpt_path_path_id(path),
|
||||
xpt_path_target_id(path), this_lun) == CAM_REQ_CMP) {
|
||||
@ -2038,10 +2034,6 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX print warning? */
|
||||
if (!CAM_LUN_ONLY_32BITS(target->luns,
|
||||
scan_info->lunindex[target_id]))
|
||||
continue;
|
||||
if (CAM_CAN_GET_SIMPLE_LUN(target->luns,
|
||||
scan_info->lunindex[target_id])) {
|
||||
CAM_GET_SIMPLE_LUN(target->luns,
|
||||
|
Loading…
Reference in New Issue
Block a user