PERFORCE change 118684 for review
Scott Long
scottl at FreeBSD.org
Mon Apr 23 22:58:00 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118684
Change 118684 by scottl at scottl-x64 on 2007/04/23 22:57:58
Split out the probe periph into scsi/scsi_probe.c. Put the quirk
table and function into scsi/scsi_xpt.c. Move needed structure and
function definitions into scsi_probe.h and scsi_xpt.h. This will
be refined as the SCSI transport separation continues.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#62 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#9 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_probe.c#6 add
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#1 add
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#1 add
.. //depot/projects/scottl-camlock/src/sys/conf/files#22 edit
.. //depot/projects/scottl-camlock/src/sys/modules/cam/Makefile#10 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#62 (text+ko) ====
@@ -65,6 +65,8 @@
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
+#include <cam/scsi/scsi_xpt.h>
+#include <cam/scsi/scsi_probe.h>
#include <machine/stdarg.h> /* for xpt_print below */
#include "opt_cam.h"
@@ -90,9 +92,6 @@
void *callback_arg;
};
-SLIST_HEAD(async_list, async_node);
-SLIST_HEAD(periph_list, cam_periph);
-
/*
* This is the maximum number of high powered commands (e.g. start unit)
* that can be outstanding at a particular time.
@@ -101,119 +100,6 @@
#define CAM_MAX_HIGHPOWER 4
#endif
-/*
- * Structure for queueing a device in a run queue.
- * There is one run queue for allocating new ccbs,
- * and another for sending ccbs to the controller.
- */
-struct cam_ed_qinfo {
- cam_pinfo pinfo;
- struct cam_ed *device;
-};
-
-/*
- * The CAM EDT (Existing Device Table) contains the device information for
- * all devices for all busses in the system. The table contains a
- * cam_ed structure for each device on the bus.
- */
-struct cam_ed {
- TAILQ_ENTRY(cam_ed) links;
- struct cam_ed_qinfo alloc_ccb_entry;
- struct cam_ed_qinfo send_ccb_entry;
- struct cam_et *target;
- struct cam_sim *sim;
- lun_id_t lun_id;
- struct camq drvq; /*
- * Queue of type drivers wanting to do
- * work on this device.
- */
- struct cam_ccbq ccbq; /* Queue of pending ccbs */
- struct async_list asyncs; /* Async callback info for this B/T/L */
- struct periph_list periphs; /* All attached devices */
- u_int generation; /* Generation number */
- struct xpt_quirk_entry *quirk; /* Oddities about this device */
- /* Storage for the inquiry data */
- cam_proto protocol;
- u_int protocol_version;
- cam_xport transport;
- u_int transport_version;
- struct scsi_inquiry_data inq_data;
- u_int8_t inq_flags; /*
- * Current settings for inquiry flags.
- * This allows us to override settings
- * like disconnection and tagged
- * queuing for a device.
- */
- u_int8_t queue_flags; /* Queue flags from the control page */
- u_int8_t serial_num_len;
- u_int8_t *serial_num;
- u_int32_t qfrozen_cnt;
- u_int32_t flags;
-#define CAM_DEV_UNCONFIGURED 0x01
-#define CAM_DEV_REL_TIMEOUT_PENDING 0x02
-#define CAM_DEV_REL_ON_COMPLETE 0x04
-#define CAM_DEV_REL_ON_QUEUE_EMPTY 0x08
-#define CAM_DEV_RESIZE_QUEUE_NEEDED 0x10
-#define CAM_DEV_TAG_AFTER_COUNT 0x20
-#define CAM_DEV_INQUIRY_DATA_VALID 0x40
-#define CAM_DEV_IN_DV 0x80
-#define CAM_DEV_DV_HIT_BOTTOM 0x100
- u_int32_t tag_delay_count;
-#define CAM_TAG_DELAY_COUNT 5
- u_int32_t tag_saved_openings;
- u_int32_t refcount;
- struct callout callout;
-};
-
-/*
- * Each target is represented by an ET (Existing Target). These
- * entries are created when a target is successfully probed with an
- * identify, and removed when a device fails to respond after a number
- * of retries, or a bus rescan finds the device missing.
- */
-struct cam_et {
- TAILQ_HEAD(, cam_ed) ed_entries;
- TAILQ_ENTRY(cam_et) links;
- struct cam_eb *bus;
- target_id_t target_id;
- u_int32_t refcount;
- u_int generation;
- struct timeval last_reset;
-};
-
-/*
- * Each bus is represented by an EB (Existing Bus). These entries
- * are created by calls to xpt_bus_register and deleted by calls to
- * xpt_bus_deregister.
- */
-struct cam_eb {
- TAILQ_HEAD(, cam_et) et_entries;
- TAILQ_ENTRY(cam_eb) links;
- path_id_t path_id;
- struct cam_sim *sim;
- struct timeval last_reset;
- u_int32_t refcount;
- u_int generation;
-};
-
-struct cam_path {
- struct cam_periph *periph;
- struct cam_eb *bus;
- struct cam_et *target;
- struct cam_ed *device;
-};
-
-struct xpt_quirk_entry {
- struct scsi_inquiry_pattern inq_pat;
- u_int8_t quirks;
-#define CAM_QUIRK_NOLUNS 0x01
-#define CAM_QUIRK_NOSERIAL 0x02
-#define CAM_QUIRK_HILUNS 0x04
-#define CAM_QUIRK_NOHILUNS 0x08
- u_int mintags;
- u_int maxtags;
-};
-
static int cam_srch_hi = 0;
TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi);
static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS);
@@ -264,370 +150,6 @@
struct mtx xpt_lock;
};
-static const char quantum[] = "QUANTUM";
-static const char sony[] = "SONY";
-static const char west_digital[] = "WDIGTL";
-static const char samsung[] = "SAMSUNG";
-static const char seagate[] = "SEAGATE";
-static const char microp[] = "MICROP";
-
-static struct xpt_quirk_entry xpt_quirk_table[] =
-{
- {
- /* Reports QUEUE FULL for temporary resource shortages */
- { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP39100*", "*" },
- /*quirks*/0, /*mintags*/24, /*maxtags*/32
- },
- {
- /* Reports QUEUE FULL for temporary resource shortages */
- { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP34550*", "*" },
- /*quirks*/0, /*mintags*/24, /*maxtags*/32
- },
- {
- /* Reports QUEUE FULL for temporary resource shortages */
- { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP32275*", "*" },
- /*quirks*/0, /*mintags*/24, /*maxtags*/32
- },
- {
- /* Broken tagged queuing drive */
- { T_DIRECT, SIP_MEDIA_FIXED, microp, "4421-07*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Broken tagged queuing drive */
- { T_DIRECT, SIP_MEDIA_FIXED, "HP", "C372*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Broken tagged queuing drive */
- { T_DIRECT, SIP_MEDIA_FIXED, microp, "3391*", "x43h" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Unfortunately, the Quantum Atlas III has the same
- * problem as the Atlas II drives above.
- * Reported by: "Johan Granlund" <johan at granlund.nu>
- *
- * For future reference, the drive with the problem was:
- * QUANTUM QM39100TD-SW N1B0
- *
- * It's possible that Quantum will fix the problem in later
- * firmware revisions. If that happens, the quirk entry
- * will need to be made specific to the firmware revisions
- * with the problem.
- *
- */
- /* Reports QUEUE FULL for temporary resource shortages */
- { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM39100*", "*" },
- /*quirks*/0, /*mintags*/24, /*maxtags*/32
- },
- {
- /*
- * 18 Gig Atlas III, same problem as the 9G version.
- * Reported by: Andre Albsmeier
- * <andre.albsmeier at mchp.siemens.de>
- *
- * For future reference, the drive with the problem was:
- * QUANTUM QM318000TD-S N491
- */
- /* Reports QUEUE FULL for temporary resource shortages */
- { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM318000*", "*" },
- /*quirks*/0, /*mintags*/24, /*maxtags*/32
- },
- {
- /*
- * Broken tagged queuing drive
- * Reported by: Bret Ford <bford at uop.cs.uop.edu>
- * and: Martin Renters <martin at tdc.on.ca>
- */
- { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST410800*", "71*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- /*
- * The Seagate Medalist Pro drives have very poor write
- * performance with anything more than 2 tags.
- *
- * Reported by: Paul van der Zwan <paulz at trantor.xs4all.nl>
- * Drive: <SEAGATE ST36530N 1444>
- *
- * Reported by: Jeremy Lea <reg at shale.csir.co.za>
- * Drive: <SEAGATE ST34520W 1281>
- *
- * No one has actually reported that the 9G version
- * (ST39140*) of the Medalist Pro has the same problem, but
- * we're assuming that it does because the 4G and 6.5G
- * versions of the drive are broken.
- */
- {
- { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST34520*", "*"},
- /*quirks*/0, /*mintags*/2, /*maxtags*/2
- },
- {
- { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST36530*", "*"},
- /*quirks*/0, /*mintags*/2, /*maxtags*/2
- },
- {
- { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST39140*", "*"},
- /*quirks*/0, /*mintags*/2, /*maxtags*/2
- },
- {
- /*
- * Slow when tagged queueing is enabled. Write performance
- * steadily drops off with more and more concurrent
- * transactions. Best sequential write performance with
- * tagged queueing turned off and write caching turned on.
- *
- * PR: kern/10398
- * Submitted by: Hideaki Okada <hokada at isl.melco.co.jp>
- * Drive: DCAS-34330 w/ "S65A" firmware.
- *
- * The drive with the problem had the "S65A" firmware
- * revision, and has also been reported (by Stephen J.
- * Roznowski <sjr at home.net>) for a drive with the "S61A"
- * firmware revision.
- *
- * Although no one has reported problems with the 2 gig
- * version of the DCAS drive, the assumption is that it
- * has the same problems as the 4 gig version. Therefore
- * this quirk entries disables tagged queueing for all
- * DCAS drives.
- */
- { T_DIRECT, SIP_MEDIA_FIXED, "IBM", "DCAS*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Broken tagged queuing drive */
- { T_DIRECT, SIP_MEDIA_REMOVABLE, "iomega", "jaz*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Broken tagged queuing drive */
- { T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CFP2107*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /* This does not support other than LUN 0 */
- { T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
- },
- {
- /*
- * Broken tagged queuing drive.
- * Submitted by:
- * NAKAJI Hiroyuki <nakaji at zeisei.dpri.kyoto-u.ac.jp>
- * in PR kern/9535
- */
- { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN34324U*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Slow when tagged queueing is enabled. (1.5MB/sec versus
- * 8MB/sec.)
- * Submitted by: Andrew Gallatin <gallatin at cs.duke.edu>
- * Best performance with these drives is achieved with
- * tagged queueing turned off, and write caching turned on.
- */
- { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "WDE*", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Slow when tagged queueing is enabled. (1.5MB/sec versus
- * 8MB/sec.)
- * Submitted by: Andrew Gallatin <gallatin at cs.duke.edu>
- * Best performance with these drives is achieved with
- * tagged queueing turned off, and write caching turned on.
- */
- { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "ENTERPRISE", "*" },
- /*quirks*/0, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Doesn't handle queue full condition correctly,
- * so we need to limit maxtags to what the device
- * can handle instead of determining this automatically.
- */
- { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN321010S*", "*" },
- /*quirks*/0, /*mintags*/2, /*maxtags*/32
- },
- {
- /* Really only one LUN */
- { T_ENCLOSURE, SIP_MEDIA_FIXED, "SUN", "SENA", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* I can't believe we need a quirk for DPT volumes. */
- { T_ANY, SIP_MEDIA_FIXED|SIP_MEDIA_REMOVABLE, "DPT", "*", "*" },
- CAM_QUIRK_NOSERIAL|CAM_QUIRK_NOLUNS,
- /*mintags*/0, /*maxtags*/255
- },
- {
- /*
- * Many Sony CDROM drives don't like multi-LUN probing.
- */
- { T_CDROM, SIP_MEDIA_REMOVABLE, sony, "CD-ROM CDU*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * This drive doesn't like multiple LUN probing.
- * Submitted by: Parag Patel <parag at cgt.com>
- */
- { T_WORM, SIP_MEDIA_REMOVABLE, sony, "CD-R CDU9*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- { T_WORM, SIP_MEDIA_REMOVABLE, "YAMAHA", "CDR100*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * The 8200 doesn't like multi-lun probing, and probably
- * don't like serial number requests either.
- */
- {
- T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
- "EXB-8200*", "*"
- },
- CAM_QUIRK_NOSERIAL|CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Let's try the same as above, but for a drive that says
- * it's an IPL-6860 but is actually an EXB 8200.
- */
- {
- T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
- "IPL-6860*", "*"
- },
- CAM_QUIRK_NOSERIAL|CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * These Hitachi drives don't like multi-lun probing.
- * The PR submitter has a DK319H, but says that the Linux
- * kernel has a similar work-around for the DK312 and DK314,
- * so all DK31* drives are quirked here.
- * PR: misc/18793
- * Submitted by: Paul Haddad <paul at pth.com>
- */
- { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK31*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
- },
- {
- /*
- * The Hitachi CJ series with J8A8 firmware apparantly has
- * problems with tagged commands.
- * PR: 23536
- * Reported by: amagai at nue.org
- */
- { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK32CJ*", "J8A8" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * These are the large storage arrays.
- * Submitted by: William Carrel <william.carrel at infospace.com>
- */
- { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "OPEN*", "*" },
- CAM_QUIRK_HILUNS, 2, 1024
- },
- {
- /*
- * This old revision of the TDC3600 is also SCSI-1, and
- * hangs upon serial number probing.
- */
- {
- T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
- " TDC 3600", "U07:"
- },
- CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Maxtor Personal Storage 3000XT (Firewire)
- * hangs upon serial number probing.
- */
- {
- T_DIRECT, SIP_MEDIA_FIXED, "Maxtor",
- "1394 storage", "*"
- },
- CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Would repond to all LUNs if asked for.
- */
- {
- T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "CALIPER",
- "CP150", "*"
- },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /*
- * Would repond to all LUNs if asked for.
- */
- {
- T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
- "96X2*", "*"
- },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Submitted by: Matthew Dodd <winter at jurai.net> */
- { T_PROCESSOR, SIP_MEDIA_FIXED, "Cabletrn", "EA41*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Submitted by: Matthew Dodd <winter at jurai.net> */
- { T_PROCESSOR, SIP_MEDIA_FIXED, "CABLETRN", "EA41*", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* TeraSolutions special settings for TRC-22 RAID */
- { T_DIRECT, SIP_MEDIA_FIXED, "TERASOLU", "TRC-22", "*" },
- /*quirks*/0, /*mintags*/55, /*maxtags*/255
- },
- {
- /* Veritas Storage Appliance */
- { T_DIRECT, SIP_MEDIA_FIXED, "VERITAS", "*", "*" },
- CAM_QUIRK_HILUNS, /*mintags*/2, /*maxtags*/1024
- },
- {
- /*
- * Would respond to all LUNs. Device type and removable
- * flag are jumper-selectable.
- */
- { T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, "MaxOptix",
- "Tahiti 1", "*"
- },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* EasyRAID E5A aka. areca ARC-6010 */
- { T_DIRECT, SIP_MEDIA_FIXED, "easyRAID", "*", "*" },
- CAM_QUIRK_NOHILUNS, /*mintags*/2, /*maxtags*/255
- },
- {
- { T_ENCLOSURE, SIP_MEDIA_FIXED, "DP", "BACKPLANE", "*" },
- CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
- },
- {
- /* Default tagged queuing parameters for all devices */
- {
- T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
- /*vendor*/"*", /*product*/"*", /*revision*/"*"
- },
- /*quirks*/0, /*mintags*/2, /*maxtags*/255
- },
-};
-
-static const int xpt_quirk_table_size =
- sizeof(xpt_quirk_table) / sizeof(*xpt_quirk_table);
-
typedef enum {
DM_RET_COPY = 0x01,
DM_RET_FLAG_MASK = 0x0f,
@@ -673,22 +195,13 @@
static periph_init_t xpt_periph_init;
-static periph_init_t probe_periph_init;
-
static struct periph_driver xpt_driver =
{
xpt_periph_init, "xpt",
TAILQ_HEAD_INITIALIZER(xpt_driver.units)
};
-static struct periph_driver probe_driver =
-{
- probe_periph_init, "probe",
- TAILQ_HEAD_INITIALIZER(probe_driver.units)
-};
-
PERIPHDRIVER_DECLARE(xpt, xpt_driver);
-PERIPHDRIVER_DECLARE(probe, probe_driver);
static d_open_t xptopen;
@@ -864,17 +377,6 @@
static xpt_busfunc_t xptsetasyncbusfunc;
static cam_status xptregister(struct cam_periph *periph,
void *arg);
-static cam_status proberegister(struct cam_periph *periph,
- void *arg);
-static void probeschedule(struct cam_periph *probe_periph);
-static void probestart(struct cam_periph *periph, union ccb *start_ccb);
-static void proberequestdefaultnegotiation(struct cam_periph *periph);
-static int proberequestbackoff(struct cam_periph *periph,
- struct cam_ed *device);
-static void probedone(struct cam_periph *periph, union ccb *done_ccb);
-static void probecleanup(struct cam_periph *periph);
-static void xpt_find_quirk(struct cam_ed *device);
-static void xpt_devise_transport(struct cam_path *path);
static void xpt_set_transfer_settings(struct ccb_trans_settings *cts,
struct cam_ed *device,
int async_update);
@@ -975,12 +477,6 @@
}
static void
-probe_periph_init()
-{
-}
-
-
-static void
xptdone(struct cam_periph *periph, union ccb *done_ccb)
{
/* Caller will release the CCB */
@@ -5028,7 +4524,7 @@
* Take the default quirk entry until we have inquiry
* data and can determine a better quirk to use.
*/
- device->quirk = &xpt_quirk_table[xpt_quirk_table_size - 1];
+ device->quirk = xpt_default_quirk;
bzero(&device->inq_data, sizeof(device->inq_data));
device->inq_flags = 0;
device->queue_flags = 0;
@@ -5449,33 +4945,6 @@
}
}
-typedef enum {
- PROBE_TUR,
- PROBE_INQUIRY, /* this counts as DV0 for Basic Domain Validation */
- PROBE_FULL_INQUIRY,
- PROBE_MODE_SENSE,
- PROBE_SERIAL_NUM,
- PROBE_TUR_FOR_NEGOTIATION,
- PROBE_INQUIRY_BASIC_DV1,
- PROBE_INQUIRY_BASIC_DV2,
- PROBE_DV_EXIT
-} probe_action;
-
-typedef enum {
- PROBE_INQUIRY_CKSUM = 0x01,
- PROBE_SERIAL_CKSUM = 0x02,
- PROBE_NO_ANNOUNCE = 0x04
-} probe_flags;
-
-typedef struct {
- TAILQ_HEAD(, ccb_hdr) request_ccbs;
- probe_action action;
- union ccb saved_ccb;
- probe_flags flags;
- MD5_CTX context;
- u_int8_t digest[16];
-} probe_softc;
-
static void
xpt_scan_lun(struct cam_periph *periph, struct cam_path *path,
cam_flags flags, union ccb *request_ccb)
@@ -5545,11 +5014,7 @@
}
if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
- probe_softc *softc;
-
- softc = (probe_softc *)old_periph->softc;
- TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
- periph_links.tqe);
+ probe_insert_ccbq(old_periph, &request_ccb->ccb_h);
} else {
status = cam_periph_alloc(proberegister, NULL, probecleanup,
probestart, "probe",
@@ -5574,773 +5039,6 @@
free(done_ccb, M_TEMP);
}
-static cam_status
-proberegister(struct cam_periph *periph, void *arg)
-{
- union ccb *request_ccb; /* CCB representing the probe request */
- cam_status status;
- probe_softc *softc;
-
- request_ccb = (union ccb *)arg;
- if (periph == NULL) {
- printf("proberegister: periph was NULL!!\n");
- return(CAM_REQ_CMP_ERR);
- }
-
- if (request_ccb == NULL) {
- printf("proberegister: no probe CCB, "
- "can't register device\n");
- return(CAM_REQ_CMP_ERR);
- }
-
- softc = (probe_softc *)malloc(sizeof(*softc), M_TEMP, M_NOWAIT);
-
- if (softc == NULL) {
- printf("proberegister: Unable to probe new device. "
- "Unable to allocate softc\n");
- return(CAM_REQ_CMP_ERR);
- }
- TAILQ_INIT(&softc->request_ccbs);
- TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
- periph_links.tqe);
- softc->flags = 0;
- periph->softc = softc;
- status = cam_periph_acquire(periph);
- if (status != CAM_REQ_CMP) {
- return (status);
- }
-
-
- /*
- * Ensure we've waited at least a bus settle
- * delay before attempting to probe the device.
- * For HBAs that don't do bus resets, this won't make a difference.
- */
- cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
- scsi_delay);
- probeschedule(periph);
- return(CAM_REQ_CMP);
-}
-
-static void
-probeschedule(struct cam_periph *periph)
-{
- struct ccb_pathinq cpi;
- union ccb *ccb;
- probe_softc *softc;
-
- softc = (probe_softc *)periph->softc;
- ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
-
- xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
- cpi.ccb_h.func_code = XPT_PATH_INQ;
- xpt_action((union ccb *)&cpi);
-
- /*
- * If a device has gone away and another device, or the same one,
- * is back in the same place, it should have a unit attention
- * condition pending. It will not report the unit attention in
- * response to an inquiry, which may leave invalid transfer
- * negotiations in effect. The TUR will reveal the unit attention
- * condition. Only send the TUR for lun 0, since some devices
- * will get confused by commands other than inquiry to non-existent
- * luns. If you think a device has gone away start your scan from
- * lun 0. This will insure that any bogus transfer settings are
- * invalidated.
- *
- * If we haven't seen the device before and the controller supports
- * some kind of transfer negotiation, negotiate with the first
- * sent command if no bus reset was performed at startup. This
- * ensures that the device is not confused by transfer negotiation
- * settings left over by loader or BIOS action.
- */
- if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
- && (ccb->ccb_h.target_lun == 0)) {
- softc->action = PROBE_TUR;
- } else if ((cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) != 0
- && (cpi.hba_misc & PIM_NOBUSRESET) != 0) {
- proberequestdefaultnegotiation(periph);
- softc->action = PROBE_INQUIRY;
- } else {
- softc->action = PROBE_INQUIRY;
- }
-
- if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
- softc->flags |= PROBE_NO_ANNOUNCE;
- else
- softc->flags &= ~PROBE_NO_ANNOUNCE;
-
- xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
-}
-
-static void
-probestart(struct cam_periph *periph, union ccb *start_ccb)
-{
- /* Probe the device that our peripheral driver points to */
- struct ccb_scsiio *csio;
- probe_softc *softc;
-
- CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
-
- softc = (probe_softc *)periph->softc;
- csio = &start_ccb->csio;
-
- switch (softc->action) {
- case PROBE_TUR:
- case PROBE_TUR_FOR_NEGOTIATION:
- case PROBE_DV_EXIT:
- {
- scsi_test_unit_ready(csio,
- /*retries*/4,
- probedone,
- MSG_SIMPLE_Q_TAG,
- SSD_FULL_SIZE,
- /*timeout*/60000);
- break;
- }
- case PROBE_INQUIRY:
- case PROBE_FULL_INQUIRY:
- case PROBE_INQUIRY_BASIC_DV1:
- case PROBE_INQUIRY_BASIC_DV2:
- {
- u_int inquiry_len;
- struct scsi_inquiry_data *inq_buf;
-
- inq_buf = &periph->path->device->inq_data;
-
- /*
- * If the device is currently configured, we calculate an
- * MD5 checksum of the inquiry data, and if the serial number
- * length is greater than 0, add the serial number data
- * into the checksum as well. Once the inquiry and the
- * serial number check finish, we attempt to figure out
- * whether we still have the same device.
- */
- if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
-
- MD5Init(&softc->context);
- MD5Update(&softc->context, (unsigned char *)inq_buf,
- sizeof(struct scsi_inquiry_data));
- softc->flags |= PROBE_INQUIRY_CKSUM;
- if (periph->path->device->serial_num_len > 0) {
- MD5Update(&softc->context,
- periph->path->device->serial_num,
- periph->path->device->serial_num_len);
- softc->flags |= PROBE_SERIAL_CKSUM;
- }
- MD5Final(softc->digest, &softc->context);
- }
-
- if (softc->action == PROBE_INQUIRY)
- inquiry_len = SHORT_INQUIRY_LENGTH;
- else
- inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
-
- /*
- * Some parallel SCSI devices fail to send an
- * ignore wide residue message when dealing with
- * odd length inquiry requests. Round up to be
- * safe.
- */
- inquiry_len = roundup2(inquiry_len, 2);
-
- if (softc->action == PROBE_INQUIRY_BASIC_DV1
- || softc->action == PROBE_INQUIRY_BASIC_DV2) {
- inq_buf = malloc(inquiry_len, M_TEMP, M_NOWAIT);
- }
- if (inq_buf == NULL) {
- xpt_print(periph->path, "malloc failure- skipping Basic"
- "Domain Validation\n");
- softc->action = PROBE_DV_EXIT;
- scsi_test_unit_ready(csio,
- /*retries*/4,
- probedone,
- MSG_SIMPLE_Q_TAG,
- SSD_FULL_SIZE,
- /*timeout*/60000);
- break;
- }
- scsi_inquiry(csio,
- /*retries*/4,
- probedone,
- MSG_SIMPLE_Q_TAG,
- (u_int8_t *)inq_buf,
- inquiry_len,
- /*evpd*/FALSE,
- /*page_code*/0,
- SSD_MIN_SIZE,
- /*timeout*/60 * 1000);
- break;
- }
- case PROBE_MODE_SENSE:
- {
- void *mode_buf;
- int mode_buf_len;
-
- mode_buf_len = sizeof(struct scsi_mode_header_6)
- + sizeof(struct scsi_mode_blk_desc)
- + sizeof(struct scsi_control_page);
- mode_buf = malloc(mode_buf_len, M_TEMP, M_NOWAIT);
- if (mode_buf != NULL) {
- scsi_mode_sense(csio,
- /*retries*/4,
- probedone,
- MSG_SIMPLE_Q_TAG,
- /*dbd*/FALSE,
- SMS_PAGE_CTRL_CURRENT,
- SMS_CONTROL_MODE_PAGE,
- mode_buf,
- mode_buf_len,
- SSD_FULL_SIZE,
- /*timeout*/60000);
- break;
- }
- xpt_print(periph->path, "Unable to mode sense control page - "
- "malloc failure\n");
- softc->action = PROBE_SERIAL_NUM;
- }
- /* FALLTHROUGH */
- case PROBE_SERIAL_NUM:
- {
- struct scsi_vpd_unit_serial_number *serial_buf;
- struct cam_ed* device;
-
- serial_buf = NULL;
- device = periph->path->device;
- device->serial_num = NULL;
- device->serial_num_len = 0;
-
- if ((device->quirk->quirks & CAM_QUIRK_NOSERIAL) == 0)
- serial_buf = (struct scsi_vpd_unit_serial_number *)
- malloc(sizeof(*serial_buf), M_TEMP,
- M_NOWAIT | M_ZERO);
-
- if (serial_buf != NULL) {
- scsi_inquiry(csio,
- /*retries*/4,
- probedone,
- MSG_SIMPLE_Q_TAG,
- (u_int8_t *)serial_buf,
- sizeof(*serial_buf),
- /*evpd*/TRUE,
- SVPD_UNIT_SERIAL_NUMBER,
- SSD_MIN_SIZE,
- /*timeout*/60 * 1000);
- break;
- }
- /*
- * We'll have to do without, let our probedone
- * routine finish up for us.
- */
- start_ccb->csio.data_ptr = NULL;
- probedone(periph, start_ccb);
- return;
- }
- }
- xpt_action(start_ccb);
-}
-
-static void
-proberequestdefaultnegotiation(struct cam_periph *periph)
-{
- struct ccb_trans_settings cts;
-
- xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
- cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_USER_SETTINGS;
- xpt_action((union ccb *)&cts);
- if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- return;
- }
- cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_CURRENT_SETTINGS;
- xpt_action((union ccb *)&cts);
-}
-
-/*
- * Backoff Negotiation Code- only pertinent for SPI devices.
- */
-static int
-proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
-{
- struct ccb_trans_settings cts;
- struct ccb_trans_settings_spi *spi;
-
- memset(&cts, 0, sizeof (cts));
- xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
- cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_CURRENT_SETTINGS;
- xpt_action((union ccb *)&cts);
- if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if (bootverbose) {
- xpt_print(periph->path,
- "failed to get current device settings\n");
- }
- return (0);
- }
- if (cts.transport != XPORT_SPI) {
- if (bootverbose) {
- xpt_print(periph->path, "not SPI transport\n");
- }
- return (0);
- }
- spi = &cts.xport_specific.spi;
-
- /*
- * We cannot renegotiate sync rate if we don't have one.
- */
- if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
- if (bootverbose) {
- xpt_print(periph->path, "no sync rate known\n");
- }
- return (0);
- }
-
- /*
- * We'll assert that we don't have to touch PPR options- the
- * SIM will see what we do with period and offset and adjust
- * the PPR options as appropriate.
- */
-
- /*
- * A sync rate with unknown or zero offset is nonsensical.
- * A sync period of zero means Async.
- */
- if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
- || spi->sync_offset == 0 || spi->sync_period == 0) {
- if (bootverbose) {
- xpt_print(periph->path, "no sync rate available\n");
- }
- return (0);
- }
-
- if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
- ("hit async: giving up on DV\n"));
- return (0);
- }
-
-
- /*
- * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
- * We don't try to remember 'last' settings to see if the SIM actually
- * gets into the speed we want to set. We check on the SIM telling
- * us that a requested speed is bad, but otherwise don't try and
- * check the speed due to the asynchronous and handshake nature
- * of speed setting.
- */
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list