aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2010-07-25 15:43:52 +0000
committerAlexander Motin <mav@FreeBSD.org>2010-07-25 15:43:52 +0000
commit8edcf69406cc816bb7c64b51ec38f23d25ad4b67 (patch)
tree17a1e011d37cb64ccedab6ec54cdbac15a501c84
parentf4e7a6c3f1891945141035dfe0144611ba609d25 (diff)
downloadsrc-8edcf69406cc816bb7c64b51ec38f23d25ad4b67.tar.gz
src-8edcf69406cc816bb7c64b51ec38f23d25ad4b67.zip
Export PCI IDs of ATA/SATA controllers through CAM and ata(4) layers to
GEOM. This information needed for proper soft-RAID's on-disk metadata reading and writing.
Notes
Notes: svn path=/head/; revision=210471
-rw-r--r--sbin/camcontrol/camcontrol.c10
-rw-r--r--sys/cam/ata/ata_da.c4
-rw-r--r--sys/cam/cam_ccb.h4
-rw-r--r--sys/cam/scsi/scsi_cd.c4
-rw-r--r--sys/cam/scsi/scsi_da.c4
-rw-r--r--sys/dev/ahci/ahci.c9
-rw-r--r--sys/dev/ata/ata-all.c11
-rw-r--r--sys/dev/ata/ata-disk.c13
-rw-r--r--sys/dev/mvs/mvs.c10
-rw-r--r--sys/dev/siis/siis.c9
-rw-r--r--sys/geom/geom_disk.c12
-rw-r--r--sys/geom/geom_disk.h4
12 files changed, 88 insertions, 6 deletions
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index c39d7ba37048..9f269066f6dc 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -3083,6 +3083,14 @@ cpi_print(struct ccb_pathinq *cpi)
cpi->initiator_id);
fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
+ fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
+ adapter_str, cpi->hba_vendor);
+ fprintf(stdout, "%s HBA device ID: 0x%04x\n",
+ adapter_str, cpi->hba_device);
+ fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
+ adapter_str, cpi->hba_subvendor);
+ fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
+ adapter_str, cpi->hba_subdevice);
fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
fprintf(stdout, "%s base transfer speed: ", adapter_str);
if (cpi->base_transfer_speed > 1000)
@@ -3092,6 +3100,8 @@ cpi_print(struct ccb_pathinq *cpi)
else
fprintf(stdout, "%dKB/sec\n",
(cpi->base_transfer_speed % 1000) * 1000);
+ fprintf(stdout, "%s maximum transfer size: %u bytes\n",
+ adapter_str, cpi->maxio);
}
static int
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 08d32c3a0b94..396802656cdf 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -734,6 +734,10 @@ adaregister(struct cam_periph *periph, void *arg)
softc->disk->d_flags |= DISKFLAG_CANDELETE;
strlcpy(softc->disk->d_ident, cgd->serial_num,
MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
+ softc->disk->d_hba_vendor = cpi.hba_vendor;
+ softc->disk->d_hba_device = cpi.hba_device;
+ softc->disk->d_hba_subvendor = cpi.hba_subvendor;
+ softc->disk->d_hba_subdevice = cpi.hba_subdevice;
softc->disk->d_sectorsize = softc->params.secsize;
softc->disk->d_mediasize = (off_t)softc->params.sectors *
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 73ddb3372032..bbb506909dfe 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -596,6 +596,10 @@ struct ccb_pathinq {
char ccb_pathinq_settings_opaque[PATHINQ_SETTINGS_SIZE];
} xport_specific;
u_int maxio; /* Max supported I/O size, in bytes. */
+ u_int16_t hba_vendor; /* HBA vendor ID */
+ u_int16_t hba_device; /* HBA device ID */
+ u_int16_t hba_subvendor; /* HBA subvendor ID */
+ u_int16_t hba_subdevice; /* HBA subdevice ID */
};
/* Path Statistics CCB */
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 76ef3bdae8d8..6a73efb5ac93 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -733,6 +733,10 @@ cdregister(struct cam_periph *periph, void *arg)
else
softc->disk->d_maxsize = cpi.maxio;
softc->disk->d_flags = 0;
+ softc->disk->d_hba_vendor = cpi.hba_vendor;
+ softc->disk->d_hba_device = cpi.hba_device;
+ softc->disk->d_hba_subvendor = cpi.hba_subvendor;
+ softc->disk->d_hba_subdevice = cpi.hba_subdevice;
disk_create(softc->disk, DISK_VERSION);
cam_periph_lock(periph);
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 7095eebca9c9..8f643611c0cc 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1310,6 +1310,10 @@ daregister(struct cam_periph *periph, void *arg)
softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
strlcpy(softc->disk->d_ident, cgd->serial_num,
MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
+ softc->disk->d_hba_vendor = cpi.hba_vendor;
+ softc->disk->d_hba_device = cpi.hba_device;
+ softc->disk->d_hba_subvendor = cpi.hba_subvendor;
+ softc->disk->d_hba_subdevice = cpi.hba_subdevice;
disk_create(softc->disk, DISK_VERSION);
mtx_lock(periph->sim->mtx);
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 9de77403a5ec..2f53f822a9d0 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -2459,7 +2459,7 @@ ahci_check_ids(device_t dev, union ccb *ccb)
static void
ahciaction(struct cam_sim *sim, union ccb *ccb)
{
- device_t dev;
+ device_t dev, parent;
struct ahci_channel *ch;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahciaction func_code=%x\n",
@@ -2599,6 +2599,7 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_pathinq *cpi = &ccb->cpi;
+ parent = device_get_parent(dev);
cpi->version_num = 1; /* XXX??? */
cpi->hba_inquiry = PI_SDTR_ABLE;
if (ch->caps & AHCI_CAP_SNCQ)
@@ -2626,8 +2627,12 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
cpi->maxio = MAXPHYS;
/* ATI SB600 can't handle 256 sectors with FPDMA (NCQ). */
- if (pci_get_devid(device_get_parent(dev)) == 0x43801002)
+ if (pci_get_devid(parent) == 0x43801002)
cpi->maxio = min(cpi->maxio, 128 * 512);
+ cpi->hba_vendor = pci_get_vendor(parent);
+ cpi->hba_device = pci_get_device(parent);
+ cpi->hba_subvendor = pci_get_subvendor(parent);
+ cpi->hba_subdevice = pci_get_subdevice(parent);
cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 3f7f1a9ef3e2..8c0ea9ddadcf 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <sys/rman.h>
#include <dev/ata/ata-all.h>
+#include <dev/pci/pcivar.h>
#include <ata_if.h>
#ifdef ATA_CAM
@@ -1523,7 +1524,7 @@ ata_check_ids(device_t dev, union ccb *ccb)
static void
ataaction(struct cam_sim *sim, union ccb *ccb)
{
- device_t dev;
+ device_t dev, parent;
struct ata_channel *ch;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ataaction func_code=%x\n",
@@ -1674,6 +1675,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_pathinq *cpi = &ccb->cpi;
+ parent = device_get_parent(dev);
cpi->version_num = 1; /* XXX??? */
cpi->hba_inquiry = PI_SDTR_ABLE;
cpi->target_sprt = 0;
@@ -1702,6 +1704,13 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
cpi->protocol = PROTO_ATA;
cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
cpi->maxio = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS;
+ if (device_get_devclass(device_get_parent(parent)) ==
+ devclass_find("pci")) {
+ cpi->hba_vendor = pci_get_vendor(parent);
+ cpi->hba_device = pci_get_device(parent);
+ cpi->hba_subvendor = pci_get_subvendor(parent);
+ cpi->hba_subdevice = pci_get_subdevice(parent);
+ }
cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 722bce5d5bde..67e092e31ae5 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
#include <dev/ata/ata-disk.h>
#include <dev/ata/ata-raid.h>
+#include <dev/pci/pcivar.h>
#include <ata_if.h>
/* prototypes */
@@ -94,6 +95,7 @@ ad_attach(device_t dev)
struct ata_channel *ch = device_get_softc(device_get_parent(dev));
struct ata_device *atadev = device_get_softc(dev);
struct ad_softc *adp;
+ device_t parent;
/* check that we have a virgin disk to attach */
if (device_get_ivars(dev))
@@ -143,6 +145,17 @@ ad_attach(device_t dev)
adp->disk->d_flags |= DISKFLAG_CANDELETE;
strlcpy(adp->disk->d_ident, atadev->param.serial,
sizeof(adp->disk->d_ident));
+ parent = device_get_parent(ch->dev);
+ if (parent != NULL && device_get_parent(parent) != NULL &&
+ (device_get_devclass(parent) ==
+ devclass_find("atapci") ||
+ device_get_devclass(device_get_parent(parent)) ==
+ devclass_find("pci"))) {
+ adp->disk->d_hba_vendor = pci_get_vendor(parent);
+ adp->disk->d_hba_device = pci_get_device(parent);
+ adp->disk->d_hba_subvendor = pci_get_subvendor(parent);
+ adp->disk->d_hba_subdevice = pci_get_subdevice(parent);
+ }
ata_disk_firmware_geom_adjust(adp->disk);
disk_create(adp->disk, DISK_VERSION);
device_add_child(dev, "subdisk", device_get_unit(dev));
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index a7800ec689bc..6b08222de6a7 100644
--- a/sys/dev/mvs/mvs.c
+++ b/sys/dev/mvs/mvs.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/bus.h>
#include <sys/rman.h>
+#include <dev/pci/pcivar.h>
#include "mvs.h"
#include <cam/cam.h>
@@ -2017,7 +2018,7 @@ mvs_check_ids(device_t dev, union ccb *ccb)
static void
mvsaction(struct cam_sim *sim, union ccb *ccb)
{
- device_t dev;
+ device_t dev, parent;
struct mvs_channel *ch;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mvsaction func_code=%x\n",
@@ -2152,6 +2153,7 @@ mvsaction(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_pathinq *cpi = &ccb->cpi;
+ parent = device_get_parent(dev);
cpi->version_num = 1; /* XXX??? */
cpi->hba_inquiry = PI_SDTR_ABLE;
if (!(ch->quirks & MVS_Q_GENI)) {
@@ -2180,6 +2182,12 @@ mvsaction(struct cam_sim *sim, union ccb *ccb)
cpi->protocol = PROTO_ATA;
cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
cpi->maxio = MAXPHYS;
+ if ((ch->quirks & MVS_Q_SOC) == 0) {
+ cpi->hba_vendor = pci_get_vendor(parent);
+ cpi->hba_device = pci_get_device(parent);
+ cpi->hba_subvendor = pci_get_subvendor(parent);
+ cpi->hba_subdevice = pci_get_subdevice(parent);
+ }
cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 6b25d4b15570..34a77fc6a7ae 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1677,7 +1677,7 @@ siis_check_ids(device_t dev, union ccb *ccb)
static void
siisaction(struct cam_sim *sim, union ccb *ccb)
{
- device_t dev;
+ device_t dev, parent;
struct siis_channel *ch;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("siisaction func_code=%x\n",
@@ -1816,6 +1816,7 @@ siisaction(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_pathinq *cpi = &ccb->cpi;
+ parent = device_get_parent(dev);
cpi->version_num = 1; /* XXX??? */
cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
cpi->hba_inquiry |= PI_SATAPM;
@@ -1835,8 +1836,12 @@ siisaction(struct cam_sim *sim, union ccb *ccb)
cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
cpi->protocol = PROTO_ATA;
cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
- cpi->ccb_h.status = CAM_REQ_CMP;
cpi->maxio = MAXPHYS;
+ cpi->hba_vendor = pci_get_vendor(parent);
+ cpi->hba_device = pci_get_device(parent);
+ cpi->hba_subvendor = pci_get_subvendor(parent);
+ cpi->hba_subdevice = pci_get_subdevice(parent);
+ cpi->ccb_h.status = CAM_REQ_CMP;
break;
}
default:
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 4cf3196d406e..25d2e3b92e6f 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -305,6 +305,18 @@ g_disk_start(struct bio *bp)
break;
else if (g_handleattr_str(bp, "GEOM::ident", dp->d_ident))
break;
+ else if (g_handleattr(bp, "GEOM::hba_vendor",
+ &dp->d_hba_vendor, 2))
+ break;
+ else if (g_handleattr(bp, "GEOM::hba_device",
+ &dp->d_hba_device, 2))
+ break;
+ else if (g_handleattr(bp, "GEOM::hba_subvendor",
+ &dp->d_hba_subvendor, 2))
+ break;
+ else if (g_handleattr(bp, "GEOM::hba_subdevice",
+ &dp->d_hba_subdevice, 2))
+ break;
else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
g_disk_kerneldump(bp, dp);
else
diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h
index 5e9d1aae6c2f..01dd73236caa 100644
--- a/sys/geom/geom_disk.h
+++ b/sys/geom/geom_disk.h
@@ -85,6 +85,10 @@ struct disk {
u_int d_stripeoffset;
u_int d_stripesize;
char d_ident[DISK_IDENT_SIZE];
+ uint16_t d_hba_vendor;
+ uint16_t d_hba_device;
+ uint16_t d_hba_subvendor;
+ uint16_t d_hba_subdevice;
/* Fields private to the driver */
void *d_drv1;