summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_periph.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/cam_periph.c')
-rw-r--r--sys/cam/cam_periph.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 468354e..c4e0b04 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam.h>
#include <cam/cam_ccb.h>
+#include <cam/cam_queue.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_periph.h>
#include <cam/cam_debug.h>
@@ -570,6 +571,8 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
u_int32_t lengths[CAM_PERIPH_MAXMAPS];
u_int32_t dirs[CAM_PERIPH_MAXMAPS];
+ /* Some controllers may not be able to handle more data. */
+ size_t maxmap = DFLTPHYS;
switch(ccb->ccb_h.func_code) {
case XPT_DEV_MATCH:
@@ -592,6 +595,11 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
dirs[0] = CAM_DIR_IN;
numbufs = 1;
}
+ /*
+ * This request will not go to the hardware, no reason
+ * to be so strict. vmapbuf() is able to map up to MAXPHYS.
+ */
+ maxmap = MAXPHYS;
break;
case XPT_SCSI_IO:
case XPT_CONT_TARGET_IO:
@@ -603,6 +611,15 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
numbufs = 1;
break;
+ case XPT_ATA_IO:
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
+ return(0);
+
+ data_ptrs[0] = &ccb->ataio.data_ptr;
+ lengths[0] = ccb->ataio.dxfer_len;
+ dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
+ numbufs = 1;
+ break;
default:
return(EINVAL);
break; /* NOTREACHED */
@@ -625,12 +642,12 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
* boundary.
*/
if ((lengths[i] +
- (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)) > DFLTPHYS){
+ (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)) > maxmap){
printf("cam_periph_mapmem: attempt to map %lu bytes, "
- "which is greater than DFLTPHYS(%d)\n",
+ "which is greater than %lu\n",
(long)(lengths[i] +
(((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)),
- DFLTPHYS);
+ (u_long)maxmap);
return(E2BIG);
}
@@ -662,7 +679,7 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
/* put our pointer in the data slot */
mapinfo->bp[i]->b_data = *data_ptrs[i];
- /* set the transfer length, we know it's < DFLTPHYS */
+ /* set the transfer length, we know it's < MAXPHYS */
mapinfo->bp[i]->b_bufsize = lengths[i];
/* set the direction */
@@ -738,6 +755,10 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
data_ptrs[0] = &ccb->csio.data_ptr;
numbufs = min(mapinfo->num_bufs_used, 1);
break;
+ case XPT_ATA_IO:
+ data_ptrs[0] = &ccb->ataio.data_ptr;
+ numbufs = min(mapinfo->num_bufs_used, 1);
+ break;
default:
/* allow ourselves to be swapped once again */
PRELE(curproc);
@@ -1583,6 +1604,13 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
xpt_print(ccb->ccb_h.path, "AutoSense Failed\n");
error = EIO; /* we have to kill the command */
break;
+ case CAM_ATA_STATUS_ERROR:
+ if (bootverbose && printed == 0) {
+ xpt_print(ccb->ccb_h.path,
+ "Request completed with CAM_ATA_STATUS_ERROR\n");
+ printed++;
+ }
+ /* FALLTHROUGH */
case CAM_REQ_CMP_ERR:
if (bootverbose && printed == 0) {
xpt_print(ccb->ccb_h.path,
OpenPOWER on IntegriCloud