svn commit: r195534 - in head: etc/mtree include lib/libcam sbin/camcontrol share/man/man4 sys/cam sys/cam/ata sys/cam/scsi sys/conf sys/dev/advansys sys/dev/ahci sys/dev/aic7xxx sys/dev/amd sys/de...

Paul B. Mahol onemda at gmail.com
Sat Jul 11 10:12:28 UTC 2009


On 7/10/09, Scott Long <scottl at freebsd.org> wrote:
> Author: scottl
> Date: Fri Jul 10 08:18:08 2009
> New Revision: 195534
> URL: http://svn.freebsd.org/changeset/base/195534
>
> Log:
>   Separate the parallel scsi knowledge out of the core of the XPT, and
>   modularize it so that new transports can be created.
>
>   Add a transport for SATA
>
>   Add a periph+protocol layer for ATA
>
>   Add a driver for AHCI-compliant hardware.
>
>   Add a maxio field to CAM so that drivers can advertise their max
>   I/O capability.  Modify various drivers so that they are insulated
>   from the value of MAXPHYS.
>
>   The new ATA/SATA code supports AHCI-compliant hardware, and will override
>   the classic ATA driver if it is loaded as a module at boot time or
> compiled
>   into the kernel.  The stack now support NCQ (tagged queueing) for
> increased
>   performance on modern SATA drives.  It also supports port multipliers.
>
>   ATA drives are accessed via 'ada' device nodes.  ATAPI drives are
>   accessed via 'cd' device nodes.  They can all be enumerated and
> manipulated
>   via camcontrol, just like SCSI drives.  SCSI commands are not translated
> to
>   their ATA equivalents; ATA native commands are used throughout the entire
>   stack, including camcontrol.  See the camcontrol manpage for further
>   details.  Testing this code may require that you update your fstab, and
>   possibly modify your BIOS to enable AHCI functionality, if available.
>
>   This code is very experimental at the moment.  The userland ABI/API has
>   changed, so applications will need to be recompiled.  It may change
>   further in the near future.  The 'ada' device name may also change as
>   more infrastructure is completed in this project.  The goal is to
>   eventually put all CAM busses and devices until newbus, allowing for
>   interesting topology and management options.
>
>   Few functional changes will be seen with existing SCSI/SAS/FC drivers,
>   though the userland ABI has still changed.  In the future, transports
>   specific modules for SAS and FC may appear in order to better support
>   the topologies and capabilities of these technologies.
>
>   The modularization of CAM and the addition of the ATA/SATA modules is
>   meant to break CAM out of the mold of being specific to SCSI, letting it
>   grow to be a framework for arbitrary transports and protocols.  It also
>   allows drivers to be written to support discrete hardware without
>   jeopardizing the stability of non-related hardware.  While only an AHCI
>   driver is provided now, a Silicon Image driver is also in the works.
>   Drivers for ICH1-4, ICH5-6, PIIX, classic IDE, and any other hardware
>   is possible and encouraged.  Help with new transports is also encouraged.
>
>   Submitted by:	scottl, mav
>   Approved by:	re

This one breaks cam.ko for me.
I can't load cam any more. I can't load ahci.ko
If I try to use umass it will panic system(obviously because cam is
never loaded in kernel)
Well that is another bug because umass should not be loaded at first place.
When trying to load cam.ko nothing verbose is displayed, just this:

module_register: module probe already exists!
Module probe failed to register: 17

Maybe because I'm using ataahci.ko and ataintel.ko?

>
> Added:
>   head/share/man/man4/ahci.4   (contents, props changed)
>   head/sys/cam/ata/
>   head/sys/cam/ata/ata_all.c   (contents, props changed)
>   head/sys/cam/ata/ata_all.h   (contents, props changed)
>   head/sys/cam/ata/ata_da.c   (contents, props changed)
>   head/sys/cam/ata/ata_xpt.c   (contents, props changed)
>   head/sys/cam/cam_xpt_internal.h   (contents, props changed)
>   head/sys/cam/scsi/scsi_xpt.c   (contents, props changed)
>   head/sys/dev/ahci/
>   head/sys/dev/ahci/ahci.c   (contents, props changed)
>   head/sys/dev/ahci/ahci.h   (contents, props changed)
>   head/sys/modules/ahci/
>   head/sys/modules/ahci/Makefile   (contents, props changed)
> Modified:
>   head/etc/mtree/BSD.include.dist
>   head/include/Makefile
>   head/lib/libcam/Makefile
>   head/sbin/camcontrol/camcontrol.8
>   head/sbin/camcontrol/camcontrol.c
>   head/share/man/man4/Makefile
>   head/sys/cam/cam.c
>   head/sys/cam/cam.h
>   head/sys/cam/cam_ccb.h
>   head/sys/cam/cam_periph.c
>   head/sys/cam/cam_xpt.c
>   head/sys/cam/cam_xpt.h
>   head/sys/cam/cam_xpt_periph.h
>   head/sys/cam/scsi/scsi_all.c
>   head/sys/cam/scsi/scsi_cd.c
>   head/sys/cam/scsi/scsi_ch.c
>   head/sys/cam/scsi/scsi_da.c
>   head/sys/cam/scsi/scsi_pass.c
>   head/sys/cam/scsi/scsi_pt.c
>   head/sys/cam/scsi/scsi_sa.c
>   head/sys/cam/scsi/scsi_ses.c
>   head/sys/cam/scsi/scsi_sg.c
>   head/sys/conf/files
>   head/sys/dev/advansys/advansys.c
>   head/sys/dev/advansys/advlib.h
>   head/sys/dev/aic7xxx/aic79xx_osm.h
>   head/sys/dev/aic7xxx/aic7xxx_osm.h
>   head/sys/dev/amd/amd.h
>   head/sys/dev/ata/atapi-cam.c
>   head/sys/dev/ciss/ciss.c
>   head/sys/dev/ciss/cissvar.h
>   head/sys/dev/isp/isp_freebsd.h
>   head/sys/dev/mfi/mfi.c
>   head/sys/dev/mfi/mfivar.h
>   head/sys/dev/mlx/mlx.c
>   head/sys/dev/mlx/mlxvar.h
>   head/sys/dev/mpt/mpt.h
>   head/sys/dev/mpt/mpt_pci.c
>   head/sys/dev/trm/trm.h
>   head/sys/modules/Makefile
>   head/sys/modules/cam/Makefile
>
> Modified: head/etc/mtree/BSD.include.dist
> ==============================================================================
> --- head/etc/mtree/BSD.include.dist	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/etc/mtree/BSD.include.dist	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -78,6 +78,8 @@
>          ..
>      ..
>      cam
> +        ata
> +        ..
>          scsi
>          ..
>      ..
>
> Modified: head/include/Makefile
> ==============================================================================
> --- head/include/Makefile	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/include/Makefile	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -38,7 +38,7 @@ LDIRS=	bsm cam geom net net80211 netatal
>  	nfs nfsclient nfsserver \
>  	sys vm
>
> -LSUBDIRS=	cam/scsi \
> +LSUBDIRS=	cam/ata cam/scsi \
>  	dev/acpica dev/an dev/bktr dev/firewire dev/hwpmc \
>  	dev/ic dev/iicbus ${_dev_ieee488} dev/lmc dev/ofw \
>  	dev/pbio ${_dev_powermac_nvram} dev/ppbus dev/smbus \
>
> Modified: head/lib/libcam/Makefile
> ==============================================================================
> --- head/lib/libcam/Makefile	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/lib/libcam/Makefile	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -2,7 +2,8 @@
>
>  LIB=		cam
>  SHLIBDIR?=	/lib
> -SRCS=		camlib.c scsi_cmdparse.c scsi_all.c scsi_da.c scsi_sa.c cam.c
> +SRCS=		camlib.c scsi_cmdparse.c scsi_all.c scsi_da.c scsi_sa.c cam.c \
> +		ata_all.c
>  INCS=		camlib.h
>
>  DPADD=		${LIBSBUF}
> @@ -34,7 +35,8 @@ MLINKS+=	cam.3 cam_open_device.3 \
>  		cam_cdbparse.3 csio_encode_visit.3 \
>  		cam_cdbparse.3 buff_encode_visit.3
>
> -.PATH:		${.CURDIR}/../../sys/cam/scsi ${.CURDIR}/../../sys/cam
> +.PATH:		${.CURDIR}/../../sys/cam/scsi ${.CURDIR}/../../sys/cam/ata \
> +		${.CURDIR}/../../sys/cam
>
>  SDIR=		${.CURDIR}/../../sys
>  CFLAGS+=	-I${.CURDIR} -I${SDIR}
>
> Modified: head/sbin/camcontrol/camcontrol.8
> ==============================================================================
> --- head/sbin/camcontrol/camcontrol.8	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/sbin/camcontrol/camcontrol.8	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -27,7 +27,7 @@
>  .\"
>  .\" $FreeBSD$
>  .\"
> -.Dd August 21, 2006
> +.Dd June 29, 2009
>  .Dt CAMCONTROL 8
>  .Os
>  .Sh NAME
> @@ -59,6 +59,10 @@
>  .Op Fl S
>  .Op Fl R
>  .Nm
> +.Ic identify
> +.Op device id
> +.Op generic args
> +.Nm
>  .Ic reportluns
>  .Op device id
>  .Op generic args
> @@ -283,6 +287,8 @@ This is to aid in script writing.
>  .It Fl R
>  Print out transfer rate information.
>  .El
> +.It Ic identify
> +Send a ATA identify command (0xec) to a device.
>  .It Ic reportluns
>  Send the SCSI REPORT LUNS (0xA0) command to the given device.
>  By default,
>
> Modified: head/sbin/camcontrol/camcontrol.c
> ==============================================================================
> --- head/sbin/camcontrol/camcontrol.c	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/sbin/camcontrol/camcontrol.c	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/ioctl.h>
>  #include <sys/stdint.h>
>  #include <sys/types.h>
> +#include <sys/endian.h>
>
>  #include <stdio.h>
>  #include <stdlib.h>
> @@ -49,6 +50,7 @@ __FBSDID("$FreeBSD$");
>  #include <cam/scsi/scsi_da.h>
>  #include <cam/scsi/scsi_pass.h>
>  #include <cam/scsi/scsi_message.h>
> +#include <cam/ata/ata_all.h>
>  #include <camlib.h>
>  #include "camcontrol.h"
>
> @@ -71,7 +73,8 @@ typedef enum {
>  	CAM_CMD_RATE		= 0x0000000f,
>  	CAM_CMD_DETACH		= 0x00000010,
>  	CAM_CMD_REPORTLUNS	= 0x00000011,
> -	CAM_CMD_READCAP		= 0x00000012
> +	CAM_CMD_READCAP		= 0x00000012,
> +	CAM_CMD_IDENTIFY	= 0x00000013
>  } cam_cmdmask;
>
>  typedef enum {
> @@ -126,6 +129,7 @@ struct camcontrol_opts option_table[] =
>  #ifndef MINIMALISTIC
>  	{"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
>  	{"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
> +	{"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
>  	{"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
>  	{"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
>  	{"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
> @@ -401,19 +405,35 @@ getdevtree(void)
>  				} else
>  					skip_device = 0;
>
> -				cam_strvis(vendor, dev_result->inq_data.vendor,
> +				if (dev_result->protocol == PROTO_SCSI) {
> +				    cam_strvis(vendor, dev_result->inq_data.vendor,
>  					   sizeof(dev_result->inq_data.vendor),
>  					   sizeof(vendor));
> -				cam_strvis(product,
> +				    cam_strvis(product,
>  					   dev_result->inq_data.product,
>  					   sizeof(dev_result->inq_data.product),
>  					   sizeof(product));
> -				cam_strvis(revision,
> +				    cam_strvis(revision,
>  					   dev_result->inq_data.revision,
>  					  sizeof(dev_result->inq_data.revision),
>  					   sizeof(revision));
> -				sprintf(tmpstr, "<%s %s %s>", vendor, product,
> +				    sprintf(tmpstr, "<%s %s %s>", vendor, product,
>  					revision);
> +				} else if (dev_result->protocol == PROTO_ATA ||
> +				    dev_result->protocol == PROTO_SATAPM) {
> +				    cam_strvis(product,
> +					   dev_result->ident_data.model,
> +					   sizeof(dev_result->ident_data.model),
> +					   sizeof(product));
> +				    cam_strvis(revision,
> +					   dev_result->ident_data.revision,
> +					  sizeof(dev_result->ident_data.revision),
> +					   sizeof(revision));
> +				    sprintf(tmpstr, "<%s %s>", product,
> +					revision);
> +				} else {
> +				    sprintf(tmpstr, "<>");
> +				}
>  				if (need_close) {
>  					fprintf(stdout, ")\n");
>  					need_close = 0;
> @@ -899,6 +919,14 @@ scsixferrate(struct cam_device *device)
>  		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
>  			freq = scsi_calc_syncsrate(spi->sync_period);
>  			speed = freq;
> +		} else {
> +			struct ccb_pathinq cpi;
> +
> +			retval = get_cpi(device, &cpi);
> +			if (retval == 0) {
> +				speed = cpi.base_transfer_speed;
> +				freq = 0;
> +			}
>  		}
>
>  		fprintf(stdout, "%s%d: ", device->device_name,
> @@ -974,6 +1002,224 @@ xferrate_bailout:
>
>  	return(retval);
>  }
> +
> +static void
> +atacapprint(struct ata_params *parm)
> +{
> +	u_int32_t lbasize = (u_int32_t)parm->lba_size_1 |
> +				((u_int32_t)parm->lba_size_2 << 16);
> +
> +	u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) |
> +				((u_int64_t)parm->lba_size48_2 << 16) |
> +				((u_int64_t)parm->lba_size48_3 << 32) |
> +				((u_int64_t)parm->lba_size48_4 << 48);
> +
> +	printf("\n");
> +	printf("Protocol              ");
> +	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
> +		if (parm->satacapabilities & ATA_SATA_GEN2)
> +			printf("SATA revision 2.x\n");
> +		else if (parm->satacapabilities & ATA_SATA_GEN1)
> +			printf("SATA revision 1.x\n");
> +		else
> +			printf("Unknown SATA revision\n");
> +	}
> +	else
> +		printf("ATA/ATAPI revision %d\n", ata_version(parm->version_major));
> +	printf("device model          %.40s\n", parm->model);
> +	printf("serial number         %.20s\n", parm->serial);
> +	printf("firmware revision     %.8s\n", parm->revision);
> +
> +	printf("cylinders             %d\n", parm->cylinders);
> +	printf("heads                 %d\n", parm->heads);
> +	printf("sectors/track         %d\n", parm->sectors);
> +
> +	if (parm->config == ATA_PROTO_CFA ||
> +	    (parm->support.command2 & ATA_SUPPORT_CFA))
> +		printf("CFA supported\n");
> +
> +	printf("lba%ssupported         ",
> +		parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not ");
> +	if (lbasize)
> +		printf("%d sectors\n", lbasize);
> +	else
> +		printf("\n");
> +
> +	printf("lba48%ssupported       ",
> +		parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not ");
> +	if (lbasize48)
> +		printf("%ju sectors\n", (uintmax_t)lbasize48);
> +	else
> +		printf("\n");
> +
> +	printf("dma%ssupported\n",
> +		parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not ");
> +
> +	printf("overlap%ssupported\n",
> +		parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not ");
> +
> +	printf("\nFeature                      "
> +		"Support  Enable    Value           Vendor\n");
> +
> +	printf("write cache                    %s	%s\n",
> +		parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no",
> +		parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no");
> +
> +	printf("read ahead                     %s	%s\n",
> +		parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no",
> +		parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no");
> +
> +	if (parm->satacapabilities && parm->satacapabilities != 0xffff) {
> +		printf("Native Command Queuing (NCQ)   %s	%s"
> +			"	%d/0x%02X\n",
> +			parm->satacapabilities & ATA_SUPPORT_NCQ ?
> +				"yes" : "no", " -",
> +			(parm->satacapabilities & ATA_SUPPORT_NCQ) ?
> +				ATA_QUEUE_LEN(parm->queue) : 0,
> +			(parm->satacapabilities & ATA_SUPPORT_NCQ) ?
> +				ATA_QUEUE_LEN(parm->queue) : 0);
> +	}
> +	printf("Tagged Command Queuing (TCQ)   %s	%s	%d/0x%02X\n",
> +		parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
> +		parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no",
> +		ATA_QUEUE_LEN(parm->queue), ATA_QUEUE_LEN(parm->queue));
> +
> +	printf("SMART                          %s	%s\n",
> +		parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no",
> +		parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no");
> +
> +	printf("microcode download             %s	%s\n",
> +		parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no",
> +		parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no");
> +
> +	printf("security                       %s	%s\n",
> +		parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no",
> +		parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no");
> +
> +	printf("power management               %s	%s\n",
> +		parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no",
> +		parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no");
> +
> +	printf("advanced power management      %s	%s	%d/0x%02X\n",
> +		parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no",
> +		parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no",
> +		parm->apm_value, parm->apm_value);
> +
> +	printf("automatic acoustic management  %s	%s	"
> +		"%d/0x%02X	%d/0x%02X\n",
> +		parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
> +		parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no",
> +		ATA_ACOUSTIC_CURRENT(parm->acoustic),
> +		ATA_ACOUSTIC_CURRENT(parm->acoustic),
> +		ATA_ACOUSTIC_VENDOR(parm->acoustic),
> +		ATA_ACOUSTIC_VENDOR(parm->acoustic));
> +}
> +
> +
> +static int
> +ataidentify(struct cam_device *device, int retry_count, int timeout)
> +{
> +	union ccb *ccb;
> +	struct ata_params *ident_buf;
> +	int error = 0;
> +	int16_t *ptr;
> +	
> +	ccb = cam_getccb(device);
> +
> +	if (ccb == NULL) {
> +		warnx("couldn't allocate CCB");
> +		return(1);
> +	}
> +
> +	/* cam_getccb cleans up the header, caller has to zero the payload */
> +	bzero(&(&ccb->ccb_h)[1],
> +	      sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
> +
> +	ident_buf = (struct ata_params *)malloc(
> +		sizeof(struct ata_params));
> +
> +	if (ident_buf == NULL) {
> +		cam_freeccb(ccb);
> +		warnx("can't malloc memory for identify\n");
> +		return(1);
> +	}
> +	bzero(ident_buf, sizeof(*ident_buf));
> +
> +	cam_fill_ataio(&ccb->ataio,
> +		      retry_count,
> +		      NULL,
> +		      /*flags*/CAM_DIR_IN,
> +		      MSG_SIMPLE_Q_TAG,
> +		      /*data_ptr*/(u_int8_t *)ident_buf,
> +		      /*dxfer_len*/sizeof(struct ata_params),
> +		      timeout ? timeout : 30 * 1000);
> +//	if (periph->path->device->protocol == PROTO_ATA)
> +		ata_36bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
> +//	else
> +//		ata_36bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
> +
> +	/* Disable freezing the device queue */
> +	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
> +
> +	if (arglist & CAM_ARG_ERR_RECOVER)
> +		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
> +
> +	if (cam_send_ccb(device, ccb) < 0) {
> +		perror("error sending ATA identify");
> +
> +		if (arglist & CAM_ARG_VERBOSE) {
> +			cam_error_print(device, ccb, CAM_ESF_ALL,
> +					CAM_EPF_ALL, stderr);
> +		}
> +
> +		cam_freeccb(ccb);
> +		return(1);
> +	}
> +
> +	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
> +		error = 1;
> +
> +		if (arglist & CAM_ARG_VERBOSE) {
> +			cam_error_print(device, ccb, CAM_ESF_ALL,
> +					CAM_EPF_ALL, stderr);
> +		}
> +	}
> +
> +	cam_freeccb(ccb);
> +
> +	if (error != 0) {
> +		free(ident_buf);
> +		return(error);
> +	}
> +
> +	for (ptr = (int16_t *)ident_buf;
> +	     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
> +		*ptr = le16toh(*ptr);
> +	}
> +	if (strncmp(ident_buf->model, "FX", 2) &&
> +	    strncmp(ident_buf->model, "NEC", 3) &&
> +	    strncmp(ident_buf->model, "Pioneer", 7) &&
> +	    strncmp(ident_buf->model, "SHARP", 5)) {
> +		ata_bswap(ident_buf->model, sizeof(ident_buf->model));
> +		ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
> +		ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
> +	}
> +	ata_btrim(ident_buf->model, sizeof(ident_buf->model));
> +	ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
> +	ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
> +	ata_bpack(ident_buf->revision, ident_buf->revision,
> sizeof(ident_buf->revision));
> +	ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
> +	ata_bpack(ident_buf->serial, ident_buf->serial,
> sizeof(ident_buf->serial));
> +
> +	fprintf(stdout, "%s%d: ", device->device_name,
> +		device->dev_unit_num);
> +	ata_print_ident(ident_buf);
> +	atacapprint(ident_buf);
> +
> +	free(ident_buf);
> +
> +	return(0);
> +}
>  #endif /* MINIMALISTIC */
>
>  /*
> @@ -3675,6 +3921,7 @@ usage(int verbose)
>  "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
>  "        camcontrol tur        [dev_id][generic args]\n"
>  "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
> +"        camcontrol identify   [dev_id][generic args]\n"
>  "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r
> report]\n"
>  "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H]
> [-N]\n"
>  "                              [-q] [-s]\n"
> @@ -3710,6 +3957,7 @@ usage(int verbose)
>  "periphlist  list all CAM peripheral drivers attached to a device\n"
>  "tur         send a test unit ready to the named device\n"
>  "inquiry     send a SCSI inquiry command to the named device\n"
> +"identify    send a ATA identify command to the named device\n"
>  "reportluns  send a SCSI report luns command to the device\n"
>  "readcap     send a SCSI read capacity command to the device\n"
>  "start       send a Start Unit command to the device\n"
> @@ -4035,6 +4283,9 @@ main(int argc, char **argv)
>  			error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
>  					      retry_count, timeout);
>  			break;
> +		case CAM_CMD_IDENTIFY:
> +			error = ataidentify(cam_dev, retry_count, timeout);
> +			break;
>  		case CAM_CMD_STARTSTOP:
>  			error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
>  					  arglist & CAM_ARG_EJECT, retry_count,
>
> Modified: head/share/man/man4/Makefile
> ==============================================================================
> --- head/share/man/man4/Makefile	Fri Jul 10 07:21:26 2009	(r195533)
> +++ head/share/man/man4/Makefile	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -23,6 +23,7 @@ MAN=	aac.4 \
>  	aha.4 \
>  	ahb.4 \
>  	ahc.4 \
> +	ahci.4 \
>  	ahd.4 \
>  	aio.4 \
>  	alc.4 \
>
> Added: head/share/man/man4/ahci.4
> ==============================================================================
> --- /dev/null	00:00:00 1970	(empty, because file is newly added)
> +++ head/share/man/man4/ahci.4	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -0,0 +1,132 @@
> +.\" Copyright (c) 2009 Alexander Motin <mav at 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.
> +.\" 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.
> +.\" 3. 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 ``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$
> +.\"
> +.Dd June 26, 2009
> +.Dt AHCI 4
> +.Os
> +.Sh NAME
> +.Nm ahci
> +.Nd Serial ATA Advanced Host Controller Interface driver
> +.Sh SYNOPSIS
> +To compile this driver into the kernel,
> +place the following lines in your
> +kernel configuration file:
> +.Bd -ragged -offset indent
> +.Cd "device pci"
> +.Cd "device scbus"
> +.Cd "device ahci"
> +.Ed
> +.Pp
> +Alternatively, to load the driver as a
> +module at boot time, place the following line in
> +.Xr loader.conf 5 :
> +.Bd -literal -offset indent
> +ahci_load="YES"
> +.Ed
> +.Pp
> +The following tunables are settable from the loader:
> +.Bl -ohang
> +.It Va hint.ahci.X.msi
> +controls Message Signaled Interrupts (MSI) usage by the specified
> controller
> +.Bl -tag -compact
> +.It 0
> +MSI disabled;
> +.It 1
> +single MSI vector used, if supported (default);
> +.It 2
> +multiple MSI vectors used, if supported;
> +.El
> +.It Va hint.ahcich.X.pm_level
> +controls SATA interface Power Management for specified channel,
> +allowing some power to be saved at the cost of additional command
> +latency.
> +Possible values:
> +.Bl -tag -compact
> +.It 0
> +interface Power Management is disabled (default);
> +.It 1
> +device is allowed to initiate PM state change, host is passive;
> +.It 2
> +host initiates PARTIAL PM state transition every time port becomes idle;
> +.It 3
> +host initiates SLUMBER PM state transition every time port becomes idle.
> +.El
> +Note that interface Power Management is not compatible with
> +device presence detection.
> +You will have to reset bus manually on device hot-plug.
> +.It Va hint.ahcich.X.sata_rev
> +setting to nonzero value limits maximum SATA revision (speed).
> +Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps.
> +.El
> +.Sh DESCRIPTION
> +This driver provides the CAM subsystem with native access to the
> +.Tn SATA
> +ports of AHCI-compatible controllers.
> +Each SATA port found is represented to CAM as a separate bus with one
> +target, or, if HBA supports Port Multipliers, 15 targets.
> +Most of the bus-management details are handled by the SATA-specific
> +transport of CAM.
> +Connected ATA disks are handled by the ATA protocol disk peripheral driver
> +.Xr ada 4 .
> +ATAPI devices are handled by the SCSI protocol peripheral drivers
> +.Xr cd 4 ,
> +.Xr da 4 ,
> +.Xr sa 4 ,
> +etc.
> +.Pp
> +Driver features include support for Serial ATA and ATAPI devices,
> +Port Multipliers, hardware command queues (up to 32 commands per port),
> +Native Command Queuing, SATA interface Power Management, device hot-plug
> +and Message Signaled Interrupts.
> +.Pp
> +The Port Multiplier FIS Based Switching feature added in the AHCI 1.2
> +specification, which is required for effective parallel operation of
> devices
> +behind Port Multipliers, is not yet supported.
> +.Pp
> +AHCI hardware is also supported by ataahci driver from
> +.Xr ata 4
> +subsystem. If both drivers are loaded at the same time, this one will be
> +given precedence as the more functional of the two.
> +.Sh HARDWARE
> +The
> +.Nm
> +driver supports AHCI compatible controllers having PCI class 1 (mass
> storage),
> +subclass 6 (SATA) and programming interface 1 (AHCI).
> +.Sh SEE ALSO
> +.Xr ada 4 ,
> +.Xr cd 4 ,
> +.Xr da 4 ,
> +.Xr sa 4 ,
> +.Xr scsi 4 ,
> +.Xr ata 4
> +.Sh HISTORY
> +The
> +.Nm
> +driver first appeared in
> +.Fx 8.0 .
> +.Sh AUTHORS
> +.An Alexander Motin Aq mav at FreeBSD.org .
>
> Added: head/sys/cam/ata/ata_all.c
> ==============================================================================
> --- /dev/null	00:00:00 1970	(empty, because file is newly added)
> +++ head/sys/cam/ata/ata_all.c	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -0,0 +1,304 @@
> +/*-
> + * Copyright (c) 2009 Alexander Motin <mav at 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.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +
> +#ifdef _KERNEL
> +#include <opt_scsi.h>
> +
> +#include <sys/systm.h>
> +#include <sys/libkern.h>
> +#include <sys/kernel.h>
> +#include <sys/sysctl.h>
> +#else
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#ifndef min
> +#define min(a,b) (((a)<(b))?(a):(b))
> +#endif
> +#endif
> +
> +#include <cam/cam.h>
> +#include <cam/cam_ccb.h>
> +#include <cam/cam_queue.h>
> +#include <cam/cam_xpt.h>
> +#include <sys/ata.h>
> +#include <cam/ata/ata_all.h>
> +#include <sys/sbuf.h>
> +#include <sys/endian.h>
> +
> +int
> +ata_version(int ver)
> +{
> +	int bit;
> +
> +	if (ver == 0xffff)
> +		return 0;
> +	for (bit = 15; bit >= 0; bit--)
> +		if (ver & (1<<bit))
> +			return bit;
> +	return 0;
> +}
> +
> +void
> +ata_print_ident(struct ata_params *ident_data)
> +{
> +	char product[48], revision[16];
> +
> +	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
> +		   sizeof(product));
> +	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
> +		   sizeof(revision));
> +	printf("<%s %s> ATA/ATAPI-%d",
> +	    product, revision, ata_version(ident_data->version_major));
> +	if (ident_data->satacapabilities && ident_data->satacapabilities !=
> 0xffff) {
> +		if (ident_data->satacapabilities & ATA_SATA_GEN2)
> +			printf(" SATA 2.x");
> +		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
> +			printf(" SATA 1.x");
> +		else
> +			printf(" SATA");
> +	}
> +	printf(" device\n");
> +}
> +
> +void
> +ata_36bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
> +    uint32_t lba, uint8_t sector_count)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = 0;
> +	ataio->cmd.command = cmd;
> +	ataio->cmd.features = features;
> +	ataio->cmd.lba_low = lba;
> +	ataio->cmd.lba_mid = lba >> 8;
> +	ataio->cmd.lba_high = lba >> 16;
> +	ataio->cmd.device = 0x40 | ((lba >> 24) & 0x0f);
> +	ataio->cmd.sector_count = sector_count;
> +}
> +
> +void
> +ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
> +    uint64_t lba, uint16_t sector_count)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = CAM_ATAIO_48BIT;
> +	ataio->cmd.command = cmd;
> +	ataio->cmd.features = features;
> +	ataio->cmd.lba_low = lba;
> +	ataio->cmd.lba_mid = lba >> 8;
> +	ataio->cmd.lba_high = lba >> 16;
> +	ataio->cmd.device = 0x40;
> +	ataio->cmd.lba_low_exp = lba >> 24;
> +	ataio->cmd.lba_mid_exp = lba >> 32;
> +	ataio->cmd.lba_high_exp = lba >> 40;
> +	ataio->cmd.features_exp = features >> 8;
> +	ataio->cmd.sector_count = sector_count;
> +	ataio->cmd.sector_count_exp = sector_count >> 8;
> +}
> +
> +void
> +ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
> +    uint64_t lba, uint16_t sector_count)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_FPDMA;
> +	ataio->cmd.command = cmd;
> +	ataio->cmd.features = sector_count;
> +	ataio->cmd.lba_low = lba;
> +	ataio->cmd.lba_mid = lba >> 8;
> +	ataio->cmd.lba_high = lba >> 16;
> +	ataio->cmd.device = 0x40;
> +	ataio->cmd.lba_low_exp = lba >> 24;
> +	ataio->cmd.lba_mid_exp = lba >> 32;
> +	ataio->cmd.lba_high_exp = lba >> 40;
> +	ataio->cmd.features_exp = sector_count >> 8;
> +}
> +
> +void
> +ata_reset_cmd(struct ccb_ataio *ataio)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT;
> +	ataio->cmd.control = 0x04;
> +}
> +
> +void
> +ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT;
> +	ataio->cmd.command = ATA_READ_PM;
> +	ataio->cmd.features = reg;
> +	ataio->cmd.features_exp = reg >> 8;
> +	ataio->cmd.device = port & 0x0f;
> +}
> +
> +void
> +ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint64_t val)
> +{
> +	bzero(&ataio->cmd, sizeof(ataio->cmd));
> +	ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT;
> +	ataio->cmd.command = ATA_WRITE_PM;
> +	ataio->cmd.features = reg;
> +	ataio->cmd.lba_low = val >> 8;
> +	ataio->cmd.lba_mid = val >> 16;
> +	ataio->cmd.lba_high = val >> 24;
> +	ataio->cmd.device = port & 0x0f;
> +	ataio->cmd.lba_low_exp = val >> 40;
> +	ataio->cmd.lba_mid_exp = val >> 48;
> +	ataio->cmd.lba_high_exp = val >> 56;
> +	ataio->cmd.features_exp = reg >> 8;
> +	ataio->cmd.sector_count = val;
> +	ataio->cmd.sector_count_exp = val >> 32;
> +}
> +
> +void
> +ata_bswap(int8_t *buf, int len)
> +{
> +	u_int16_t *ptr = (u_int16_t*)(buf + len);
> +
> +	while (--ptr >= (u_int16_t*)buf)
> +		*ptr = be16toh(*ptr);
> +}
> +
> +void
> +ata_btrim(int8_t *buf, int len)
> +{
> +	int8_t *ptr;
> +
> +	for (ptr = buf; ptr < buf+len; ++ptr)
> +		if (!*ptr || *ptr == '_')
> +			*ptr = ' ';
> +	for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
> +		*ptr = 0;
> +}
> +
> +void
> +ata_bpack(int8_t *src, int8_t *dst, int len)
> +{
> +	int i, j, blank;
> +
> +	for (i = j = blank = 0 ; i < len; i++) {
> +		if (blank && src[i] == ' ') continue;
> +		if (blank && src[i] != ' ') {
> +			dst[j++] = src[i];
> +			blank = 0;
> +			continue;
> +		}
> +		if (src[i] == ' ') {
> +			blank = 1;
> +			if (i == 0)
> +			continue;
> +		}
> +		dst[j++] = src[i];
> +	}
> +	while (j < len)
> +		dst[j++] = 0x00;
> +}
> +
> +int
> +ata_max_pmode(struct ata_params *ap)
> +{
> +    if (ap->atavalid & ATA_FLAG_64_70) {
> +	if (ap->apiomodes & 0x02)
> +	    return ATA_PIO4;
> +	if (ap->apiomodes & 0x01)
> +	    return ATA_PIO3;
> +    }
> +    if (ap->mwdmamodes & 0x04)
> +	return ATA_PIO4;
> +    if (ap->mwdmamodes & 0x02)
> +	return ATA_PIO3;
> +    if (ap->mwdmamodes & 0x01)
> +	return ATA_PIO2;
> +    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
> +	return ATA_PIO2;
> +    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
> +	return ATA_PIO1;
> +    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000)
> +	return ATA_PIO0;
> +    return ATA_PIO0;
> +}
> +
> +int
> +ata_max_wmode(struct ata_params *ap)
> +{
> +    if (ap->mwdmamodes & 0x04)
> +	return ATA_WDMA2;
> +    if (ap->mwdmamodes & 0x02)
> +	return ATA_WDMA1;
> +    if (ap->mwdmamodes & 0x01)
> +	return ATA_WDMA0;
> +    return -1;
> +}
> +
> +int
> +ata_max_umode(struct ata_params *ap)
> +{
> +    if (ap->atavalid & ATA_FLAG_88) {
> +	if (ap->udmamodes & 0x40)
> +	    return ATA_UDMA6;
> +	if (ap->udmamodes & 0x20)
> +	    return ATA_UDMA5;
> +	if (ap->udmamodes & 0x10)
> +	    return ATA_UDMA4;
> +	if (ap->udmamodes & 0x08)
> +	    return ATA_UDMA3;
> +	if (ap->udmamodes & 0x04)
> +	    return ATA_UDMA2;
> +	if (ap->udmamodes & 0x02)
> +	    return ATA_UDMA1;
> +	if (ap->udmamodes & 0x01)
> +	    return ATA_UDMA0;
> +    }
> +    return -1;
> +}
> +
> +int
> +ata_max_mode(struct ata_params *ap, int mode, int maxmode)
> +{
> +
> +    if (maxmode && mode > maxmode)
> +	mode = maxmode;
> +
> +    if (mode >= ATA_UDMA0 && ata_max_umode(ap) > 0)
> +	return (min(mode, ata_max_umode(ap)));
> +
> +    if (mode >= ATA_WDMA0 && ata_max_wmode(ap) > 0)
> +	return (min(mode, ata_max_wmode(ap)));
> +
> +    if (mode > ata_max_pmode(ap))
> +	return (min(mode, ata_max_pmode(ap)));
> +
> +    return (mode);
> +}
> +
>
> Added: head/sys/cam/ata/ata_all.h
> ==============================================================================
> --- /dev/null	00:00:00 1970	(empty, because file is newly added)
> +++ head/sys/cam/ata/ata_all.h	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -0,0 +1,105 @@
> +/*-
> + * Copyright (c) 2009 Alexander Motin <mav at 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 <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. */
> +
> +	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);
> +void	ata_print_ident(struct ata_params *ident_data);
> +
> +void	ata_36bit_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, uint64_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 mode, int maxmode);
> +
> +#endif
>
> Added: head/sys/cam/ata/ata_da.c
> ==============================================================================
> --- /dev/null	00:00:00 1970	(empty, because file is newly added)
> +++ head/sys/cam/ata/ata_da.c	Fri Jul 10 08:18:08 2009	(r195534)
> @@ -0,0 +1,1144 @@
> +/*-
> + * Copyright (c) 2009 Alexander Motin <mav at 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,
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-head at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe at freebsd.org"
>


-- 
Paul


More information about the svn-src-head mailing list