PERFORCE change 169823 for review
Alexander Motin
mav at FreeBSD.org
Mon Oct 26 11:53:15 UTC 2009
http://p4web.freebsd.org/chv.cgi?CH=169823
Change 169823 by mav at mav_mavtest on 2009/10/26 11:52:22
Move setting length of PIO transaction from ada driver to ATA XPT,
ada driver is now stateless.
Make aprobe driver to always set mode and max sectors on device.
It is required after device reset.
Make XPT to report length of PIO transaction to SIM. It is required
for correct PIO modes operation.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#34 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#44 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#28 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#31 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#20 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#34 (text+ko) ====
@@ -63,8 +63,7 @@
#define ATA_MAX_28BIT_LBA 268435455UL
typedef enum {
- ADA_STATE_NORMAL,
- ADA_STATE_SET_MULTI
+ ADA_STATE_NORMAL
} ada_state;
typedef enum {
@@ -84,7 +83,6 @@
} ada_quirks;
typedef enum {
- ADA_CCB_SET_MULTI = 0x01,
ADA_CCB_BUFFER_IO = 0x03,
ADA_CCB_WAITING = 0x04,
ADA_CCB_DUMP = 0x05,
@@ -112,7 +110,6 @@
ada_quirks quirks;
int ordered_tag_count;
int outstanding_cmds;
- int secsperint;
struct disk_params params;
struct disk *disk;
union ccb saved_ccb;
@@ -551,22 +548,6 @@
"due to status 0x%x\n", status);
break;
}
- case AC_SENT_BDR:
- case AC_BUS_RESET:
- {
- struct ada_softc *softc = (struct ada_softc *)periph->softc;
-
- cam_periph_async(periph, code, path, arg);
- if (softc->state != ADA_STATE_NORMAL)
- break;
- /*
- * Restore device configuration.
- */
- softc->state = ADA_STATE_SET_MULTI;
- cam_periph_acquire(periph);
- xpt_schedule(periph, CAM_PRIORITY_DEV);
- break;
- }
default:
cam_periph_async(periph, code, path, arg);
break;
@@ -645,8 +626,7 @@
if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
cgd->ident_data.queue >= 31)
softc->flags |= ADA_FLAG_CAN_NCQ;
- softc->secsperint = max(1, min(cgd->ident_data.sectors_intr & 0xff, 16));
- softc->state = ADA_STATE_SET_MULTI;
+ softc->state = ADA_STATE_NORMAL;
periph->softc = softc;
@@ -735,18 +715,10 @@
* them and the only alternative would be to
* not attach the device on failure.
*/
- xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
+ xpt_register_async(AC_LOST_DEVICE,
adaasync, periph, periph->path);
/*
- * Take an exclusive refcount on the periph while adastart is called
- * to finish the probe. The reference will be dropped in adadone at
- * the end of probe.
- */
- cam_periph_acquire(periph);
- xpt_schedule(periph, CAM_PRIORITY_DEV);
-
- /*
* Schedule a periodic event to occasionally send an
* ordered tag to a device.
*/
@@ -902,21 +874,6 @@
}
break;
}
- case ADA_STATE_SET_MULTI:
- {
- cam_fill_ataio(ataio,
- ada_retry_count,
- adadone,
- CAM_DIR_NONE,
- 0,
- NULL,
- 0,
- ada_default_timeout*1000);
-
- ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, softc->secsperint);
- start_ccb->ccb_h.ccb_state = ADA_CCB_SET_MULTI;
- xpt_action(start_ccb);
- }
}
}
@@ -1004,41 +961,6 @@
wakeup(&done_ccb->ccb_h.cbfcnp);
return;
}
- case ADA_CCB_SET_MULTI:
- {
- if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
- } else {
- int error;
-
- error = adaerror(done_ccb, 0, 0);
- if (error == ERESTART) {
- /* A retry was scheduled, so just return. */
- return;
- }
- if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(done_ccb->ccb_h.path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
- }
- softc->state = ADA_STATE_NORMAL;
- /*
- * Since our peripheral may be invalidated by an error
- * above or an external event, we must release our CCB
- * before releasing the probe lock on the peripheral.
- * The peripheral will only go away once the last lock
- * is removed, and we need it around for the CCB release
- * operation.
- */
- xpt_release_ccb(done_ccb);
- if (bioq_first(&softc->bio_queue) != NULL) {
- /* Have more work to do, so ensure we stay scheduled */
- xpt_schedule(periph, CAM_PRIORITY_NORMAL);
- }
- cam_periph_release_locked(periph);
- return;
- }
case ADA_CCB_DUMP:
/* No-op. We're polling */
return;
==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#44 (text+ko) ====
@@ -92,6 +92,7 @@
PROBE_RESET,
PROBE_IDENTIFY,
PROBE_SETMODE,
+ PROBE_SET_MULTI,
PROBE_INQUIRY,
PROBE_FULL_INQUIRY,
PROBE_PM_PID,
@@ -103,6 +104,7 @@
"PROBE_RESET",
"PROBE_IDENTIFY",
"PROBE_SETMODE",
+ "PROBE_SET_MULTI",
"PROBE_INQUIRY",
"PROBE_FULL_INQUIRY",
"PROBE_PM_PID",
@@ -284,12 +286,16 @@
struct ccb_ataio *ataio;
struct ccb_scsiio *csio;
probe_softc *softc;
+ struct cam_path *path;
+ struct ata_params *ident_buf;
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
softc = (probe_softc *)periph->softc;
+ path = start_ccb->ccb_h.path;
ataio = &start_ccb->ataio;
csio = &start_ccb->csio;
+ ident_buf = &periph->path->device->ident_data;
switch (softc->action) {
case PROBE_RESET:
@@ -304,10 +310,6 @@
ata_reset_cmd(ataio);
break;
case PROBE_IDENTIFY:
- {
- struct ata_params *ident_buf =
- &periph->path->device->ident_data;
-
if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
/* Prepare check that it is the same device. */
MD5_CTX context;
@@ -337,12 +339,7 @@
else
ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
break;
- }
case PROBE_SETMODE:
- {
- struct ata_params *ident_buf =
- &periph->path->device->ident_data;
-
cam_fill_ataio(ataio,
1,
probedone,
@@ -354,6 +351,37 @@
ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6));
break;
+ case PROBE_SET_MULTI:
+ {
+ struct ccb_trans_settings cts;
+ u_int sectors;
+
+ sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16));
+
+ /* Report bytecount to SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ if (path->device->transport == XPORT_ATA) {
+ cts.xport_specific.ata.bytecount = sectors * 512;
+ cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
+ } else {
+ cts.xport_specific.sata.bytecount = sectors * 512;
+ cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
+ }
+ xpt_action((union ccb *)&cts);
+
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ CAM_DIR_NONE,
+ 0,
+ NULL,
+ 0,
+ 30*1000);
+ ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors);
+ break;
}
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
@@ -408,7 +436,7 @@
ata_pm_read_cmd(ataio, 1, 15);
break;
case PROBE_INVALID:
- CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
+ CAM_DEBUG(path, CAM_DEBUG_INFO,
("probestart: invalid action state\n"));
default:
break;
@@ -666,29 +694,28 @@
/* Device changed. */
xpt_async(AC_LOST_DEVICE, path, NULL);
}
- break;
- }
+ } else {
+ /* Clean up from previous instance of this device */
+ if (path->device->serial_num != NULL) {
+ free(path->device->serial_num, M_CAMXPT);
+ path->device->serial_num = NULL;
+ path->device->serial_num_len = 0;
+ }
+ path->device->serial_num =
+ (u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
+ M_CAMXPT, M_NOWAIT);
+ if (path->device->serial_num != NULL) {
+ bcopy(ident_buf->serial,
+ path->device->serial_num,
+ sizeof(ident_buf->serial));
+ path->device->serial_num[sizeof(ident_buf->serial)]
+ = '\0';
+ path->device->serial_num_len =
+ strlen(path->device->serial_num);
+ }
- /* Clean up from previous instance of this device */
- if (path->device->serial_num != NULL) {
- free(path->device->serial_num, M_CAMXPT);
- path->device->serial_num = NULL;
- path->device->serial_num_len = 0;
- }
- path->device->serial_num =
- (u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
- M_CAMXPT, M_NOWAIT);
- if (path->device->serial_num != NULL) {
- bcopy(ident_buf->serial,
- path->device->serial_num,
- sizeof(ident_buf->serial));
- path->device->serial_num[sizeof(ident_buf->serial)]
- = '\0';
- path->device->serial_num_len =
- strlen(path->device->serial_num);
+ path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
}
-
- path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
ata_device_transport(path);
PROBE_SET_ACTION(softc, PROBE_SETMODE);
xpt_release_ccb(done_ccb);
@@ -696,21 +723,23 @@
return;
}
case PROBE_SETMODE:
- {
if (path->device->protocol == PROTO_ATA) {
+ PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
+ } else {
+ PROBE_SET_ACTION(softc, PROBE_INQUIRY);
+ }
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
+ case PROBE_SET_MULTI:
+ if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
done_ccb);
- } else {
- PROBE_SET_ACTION(softc, PROBE_INQUIRY);
- xpt_release_ccb(done_ccb);
- xpt_schedule(periph, priority);
- return;
}
break;
- }
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
{
@@ -747,10 +776,12 @@
scsi_find_quirk(path->device);
ata_device_transport(path);
- path->device->flags &= ~CAM_DEV_UNCONFIGURED;
- done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
- xpt_action(done_ccb);
- xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+ if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+ path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+ done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+ xpt_action(done_ccb);
+ xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+ }
break;
}
case PROBE_PM_PID:
==== //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#28 (text+ko) ====
@@ -816,12 +816,22 @@
u_int32_t bitrate; /* Mbps */
};
+struct ccb_trans_settings_ata {
+ u_int valid; /* Which fields to honor */
+#define CTS_ATA_VALID_MODE 0x01
+#define CTS_ATA_VALID_BYTECOUNT 0x04
+ u_int32_t mode;
+ u_int bytecount; /* Length of PIO transaction */
+};
+
struct ccb_trans_settings_sata {
u_int valid; /* Which fields to honor */
#define CTS_SATA_VALID_SPEED 0x01
#define CTS_SATA_VALID_PM 0x02
+#define CTS_SATA_VALID_BYTECOUNT 0x04
u_int32_t bitrate; /* Mbps */
u_int pm_present; /* PM is present (XPT->SIM) */
+ u_int bytecount; /* Length of PIO transaction */
};
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
@@ -841,6 +851,7 @@
struct ccb_trans_settings_spi spi;
struct ccb_trans_settings_fc fc;
struct ccb_trans_settings_sas sas;
+ struct ccb_trans_settings_ata ata;
struct ccb_trans_settings_sata sata;
} xport_specific;
};
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#31 (text+ko) ====
@@ -149,6 +149,10 @@
mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
TAILQ_INIT(&ch->ata_queue);
TASK_INIT(&ch->conntask, 0, ata_conn_event, dev);
+#ifdef ATA_CAM
+ ch->bytecount[0] = 16 * 512;
+ ch->bytecount[1] = 16 * 512;
+#endif
/* reset the controller HW, the channel and device(s) */
while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
@@ -1275,7 +1279,8 @@
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
request->flags |= ATA_R_WRITE;
}
- request->transfersize = min(request->bytecount, 16*512);
+ request->transfersize = min(request->bytecount,
+ ch->bytecount[ccb->ccb_h.target_id]);
// request->callback = ad_done;
request->retries = 0;
request->timeout = (ccb->ccb_h.timeout + 999) / 1000;
@@ -1394,12 +1399,18 @@
break;
case XPT_SET_TRAN_SETTINGS:
{
+ struct ccb_trans_settings *cts = &ccb->cts;
+
+ if (ccb->ccb_h.target_id >= 0 && ccb->ccb_h.target_id <= 1 &&
+ (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)) {
+ ch->bytecount[ccb->ccb_h.target_id] =
+ cts->xport_specific.ata.bytecount;
+ }
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
}
case XPT_GET_TRAN_SETTINGS:
- /* Get default/user set transfer settings for the target */
{
struct ccb_trans_settings *cts = &ccb->cts;
@@ -1407,8 +1418,11 @@
cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
cts->transport = XPORT_ATA;
cts->transport_version = XPORT_VERSION_UNSPECIFIED;
- cts->proto_specific.valid = 0;
- cts->xport_specific.sata.valid = 0;
+ if (ccb->ccb_h.target_id >= 0 && ccb->ccb_h.target_id <= 1) {
+ cts->proto_specific.valid = CTS_ATA_VALID_BYTECOUNT;
+ cts->xport_specific.ata.bytecount =
+ ch->bytecount[ccb->ccb_h.target_id];
+ }
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#20 (text+ko) ====
@@ -560,6 +560,7 @@
#ifdef ATA_CAM
struct cam_sim *sim;
struct cam_path *path;
+ u_int bytecount[2]; /* Length of PIO transaction */
#endif
};
More information about the p4-projects
mailing list