Date: Tue, 10 Nov 2009 15:39:31 GMT From: Alexander Motin <mav@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 170441 for review Message-ID: <200911101539.nAAFdVR3091747@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=170441 Change 170441 by mav@mav_mavbook on 2009/11/10 15:38:37 Give ATA XPT initial knowledge about command queueing. Now it sets device queue depth according to information from SIM and device. Limit queue depth for non-NCQ devices by 2 requests as compromise between request sorter effectiveness and minimal request latency. Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#53 edit .. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#77 edit .. //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#17 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#53 (text+ko) ==== @@ -66,7 +66,7 @@ #include <machine/stdarg.h> /* for xpt_print below */ #include "opt_cam.h" -struct scsi_quirk_entry { +struct ata_quirk_entry { struct scsi_inquiry_pattern inq_pat; u_int8_t quirks; #define CAM_QUIRK_NOLUNS 0x01 @@ -76,7 +76,6 @@ u_int mintags; u_int maxtags; }; -#define SCSI_QUIRK(dev) ((struct scsi_quirk_entry *)((dev)->quirk)) static periph_init_t probe_periph_init; @@ -138,7 +137,7 @@ struct cam_periph *periph; } probe_softc; -static struct scsi_quirk_entry scsi_quirk_table[] = +static struct ata_quirk_entry ata_quirk_table[] = { { /* Default tagged queuing parameters for all devices */ @@ -150,8 +149,8 @@ }, }; -static const int scsi_quirk_table_size = - sizeof(scsi_quirk_table) / sizeof(*scsi_quirk_table); +static const int ata_quirk_table_size = + sizeof(ata_quirk_table) / sizeof(*ata_quirk_table); static cam_status proberegister(struct cam_periph *periph, void *arg); @@ -162,7 +161,7 @@ // struct cam_ed *device); static void probedone(struct cam_periph *periph, union ccb *done_ccb); static void probecleanup(struct cam_periph *periph); -static void scsi_find_quirk(struct cam_ed *device); +static void ata_find_quirk(struct cam_ed *device); static void ata_scan_bus(struct cam_periph *periph, union ccb *ccb); static void ata_scan_lun(struct cam_periph *periph, struct cam_path *path, cam_flags flags, @@ -172,10 +171,9 @@ ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id); static void ata_device_transport(struct cam_path *path); -static void scsi_set_transfer_settings(struct ccb_trans_settings *cts, +static void ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, int async_update); -static void scsi_toggle_tags(struct cam_path *path); static void ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, @@ -717,6 +715,14 @@ path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; } + if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) { + path->device->mintags = path->device->maxtags = + ATA_QUEUE_LEN(ident_buf->queue) + 1; + } + ata_find_quirk(path->device); + if (path->device->mintags != 0) { + xpt_start_tags(path); + } ata_device_transport(path); PROBE_SET_ACTION(softc, PROBE_SETMODE); xpt_release_ccb(done_ccb); @@ -776,7 +782,6 @@ return; } - scsi_find_quirk(path->device); ata_device_transport(path); if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; @@ -853,24 +858,23 @@ } static void -scsi_find_quirk(struct cam_ed *device) +ata_find_quirk(struct cam_ed *device) { - struct scsi_quirk_entry *quirk; + struct ata_quirk_entry *quirk; caddr_t match; match = cam_quirkmatch((caddr_t)&device->inq_data, - (caddr_t)scsi_quirk_table, - sizeof(scsi_quirk_table) / - sizeof(*scsi_quirk_table), - sizeof(*scsi_quirk_table), scsi_inquiry_match); + (caddr_t)ata_quirk_table, + ata_quirk_table_size, + sizeof(*ata_quirk_table), scsi_inquiry_match); if (match == NULL) panic("xpt_find_quirk: device didn't match wildcard entry!!"); - quirk = (struct scsi_quirk_entry *)match; + quirk = (struct ata_quirk_entry *)match; device->quirk = quirk; - device->mintags = quirk->mintags; - device->maxtags = quirk->maxtags; +// device->mintags = quirk->mintags; +// device->maxtags = quirk->maxtags; } typedef struct { @@ -1101,7 +1105,7 @@ ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id) { struct cam_path path; - struct scsi_quirk_entry *quirk; + struct ata_quirk_entry *quirk; struct cam_ed *device; struct cam_ed *cur_device; @@ -1113,10 +1117,10 @@ * Take the default quirk entry until we have inquiry * data and can determine a better quirk to use. */ - quirk = &scsi_quirk_table[scsi_quirk_table_size - 1]; + quirk = &ata_quirk_table[ata_quirk_table_size - 1]; device->quirk = (void *)quirk; - device->mintags = quirk->mintags; - device->maxtags = quirk->maxtags; + device->mintags = 0; + device->maxtags = 0; bzero(&device->inq_data, sizeof(device->inq_data)); device->inq_flags = 0; device->queue_flags = 0; @@ -1199,7 +1203,7 @@ switch (start_ccb->ccb_h.func_code) { case XPT_SET_TRAN_SETTINGS: { - scsi_set_transfer_settings(&start_ccb->cts, + ata_set_transfer_settings(&start_ccb->cts, start_ccb->ccb_h.path->device, /*async_update*/FALSE); break; @@ -1227,7 +1231,7 @@ } static void -scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, +ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, int async_update) { struct ccb_pathinq cpi; @@ -1387,39 +1391,6 @@ (*(sim->sim_action))(sim, (union ccb *)cts); } -static void -scsi_toggle_tags(struct cam_path *path) -{ - struct cam_ed *dev; - - /* - * Give controllers a chance to renegotiate - * before starting tag operations. We - * "toggle" tagged queuing off then on - * which causes the tag enable command delay - * counter to come into effect. - */ - dev = path->device; - if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 - || ((dev->inq_flags & SID_CmdQue) != 0 - && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) { - struct ccb_trans_settings cts; - - xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); - cts.protocol = PROTO_SCSI; - cts.protocol_version = PROTO_VERSION_UNSPECIFIED; - cts.transport = XPORT_UNSPECIFIED; - cts.transport_version = XPORT_VERSION_UNSPECIFIED; - cts.proto_specific.scsi.flags = 0; - cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ; - scsi_set_transfer_settings(&cts, path->device, - /*async_update*/TRUE); - cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB; - scsi_set_transfer_settings(&cts, path->device, - /*async_update*/TRUE); - } -} - /* * Handle any per-device event notifications that require action by the XPT. */ @@ -1452,15 +1423,6 @@ status = CAM_REQ_CMP_ERR; if (status == CAM_REQ_CMP) { - - /* - * Allow transfer negotiation to occur in a - * tag free environment. - */ - if (async_code == AC_SENT_BDR - || async_code == AC_BUS_RESET) - scsi_toggle_tags(&newpath); - if (async_code == AC_INQ_CHANGED) { /* * We've sent a start unit command, or @@ -1481,7 +1443,7 @@ struct ccb_trans_settings *settings; settings = (struct ccb_trans_settings *)async_arg; - scsi_set_transfer_settings(settings, device, + ata_set_transfer_settings(settings, device, /*async_update*/TRUE); } } ==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#77 (text+ko) ==== @@ -733,7 +733,8 @@ } /* Construct SIM entry */ ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch, - device_get_unit(dev), &ch->mtx, ch->numslots, 0, devq); + device_get_unit(dev), &ch->mtx, + min(2, ch->numslots), ch->numslots, devq); if (ch->sim == NULL) { device_printf(dev, "unable to allocate sim\n"); error = ENOMEM; ==== //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#17 (text+ko) ==== @@ -454,7 +454,7 @@ } /* Construct SIM entry */ ch->sim = cam_sim_alloc(siisaction, siispoll, "siisch", ch, - device_get_unit(dev), &ch->mtx, SIIS_MAX_SLOTS, 0, devq); + device_get_unit(dev), &ch->mtx, 2, SIIS_MAX_SLOTS, devq); if (ch->sim == NULL) { device_printf(dev, "unable to allocate sim\n"); error = ENOMEM;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911101539.nAAFdVR3091747>