Lines Matching refs:mpt
1 /* $NetBSD: mpt.c,v 1.21 2019/09/23 16:19:33 skrll Exp $ */
102 * mpt.c:
106 * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
113 __KERNEL_RCSID(0, "$NetBSD: mpt.c,v 1.21 2019/09/23 16:19:33 skrll Exp $");
115 #include <dev/ic/mpt.h>
125 mpt_rd_db(mpt_softc_t *mpt)
127 return mpt_read(mpt, MPT_OFFSET_DOORBELL);
131 mpt_rd_intr(mpt_softc_t *mpt)
133 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
138 mpt_wait_db_ack(mpt_softc_t *mpt)
142 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
154 mpt_wait_db_int(mpt_softc_t *mpt)
158 if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
169 mpt_check_doorbell(mpt_softc_t *mpt)
171 u_int32_t db = mpt_rd_db(mpt);
173 mpt_prt(mpt, "Device not running");
180 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
185 u_int32_t db = mpt_rd_db(mpt);
198 mpt_soft_reset(mpt_softc_t *mpt)
200 if (mpt->verbose) {
201 mpt_prt(mpt, "soft reset");
205 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
206 mpt_prt(mpt, "soft reset failed: device not running");
214 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
215 mpt_prt(mpt, "soft reset failed: doorbell wedged");
220 mpt_write(mpt, MPT_OFFSET_DOORBELL,
222 if (mpt_wait_db_ack(mpt) != MPT_OK) {
223 mpt_prt(mpt, "soft reset failed: ack timeout");
228 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
229 mpt_prt(mpt, "soft reset failed: device did not start running");
240 mpt_hard_reset(mpt_softc_t *mpt)
242 if (mpt->verbose) {
243 mpt_prt(mpt, "hard reset");
245 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xff);
248 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
249 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2);
250 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3);
251 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4);
252 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5);
255 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC);
260 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
270 mpt_reset(mpt_softc_t *mpt)
275 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
277 mpt_hard_reset(mpt);
280 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
282 mpt_prt(mpt, "failed to reset device");
291 mpt_free_request(mpt_softc_t *mpt, request_t *req)
293 if (req == NULL || req != &mpt->request_pool[req->index]) {
300 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
305 mpt_get_request(mpt_softc_t *mpt)
308 req = SLIST_FIRST(&mpt->request_free_list);
310 if (req != &mpt->request_pool[req->index]) {
316 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
324 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
326 req->sequence = mpt->sequence++;
327 if (mpt->verbose > 1) {
330 mpt_prt(mpt, "Send Request %d (%#" PRIxBUSADDR "):",
332 mpt_prt(mpt, "%08x %08x %08x %08x",
334 mpt_prt(mpt, "%08x %08x %08x %08x",
336 mpt_prt(mpt, "%08x %08x %08x %08x",
338 mpt_prt(mpt, "%08x %08x %08x %08x",
341 MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
343 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
351 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
353 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
358 mpt_pop_reply_queue(mpt_softc_t *mpt)
360 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
370 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
376 data = mpt_rd_db(mpt);
381 mpt_prt(mpt, "handshake aborted due to invalid doorbell state");
391 if (MPT_DB_INTR(mpt_rd_intr(mpt)))
392 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
400 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
403 if (mpt_wait_db_int(mpt) != MPT_OK) {
404 mpt_prt(mpt, "mpt_send_handshake_cmd timeout1");
409 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
411 if (mpt_wait_db_ack(mpt) != MPT_OK) {
412 mpt_prt(mpt, "mpt_send_handshake_cmd timeout2");
418 mpt_write(mpt, MPT_OFFSET_DOORBELL, htole32(*data32++));
419 if (mpt_wait_db_ack(mpt) != MPT_OK) {
420 mpt_prt(mpt,
430 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
443 if (mpt_wait_db_int(mpt) != MPT_OK) {
444 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1");
447 *data16++ = le16toh(mpt_read(mpt, MPT_OFFSET_DOORBELL) &
449 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
452 if (mpt_wait_db_int(mpt) != MPT_OK) {
453 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2");
456 *data16++ = le16toh(mpt_read(mpt, MPT_OFFSET_DOORBELL) &
458 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
461 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
462 mpt_prt(mpt, "reply length does not match message length: "
473 if (mpt_wait_db_int(mpt) != MPT_OK) {
474 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3");
477 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
482 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
486 if (mpt_wait_db_int(mpt) != MPT_OK) {
487 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout4");
490 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
493 if (mpt->verbose > 1)
502 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
510 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
513 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
518 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
527 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
530 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
541 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
550 init.MaxDevices = mpt->mpt_max_devices;
555 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
559 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
569 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
577 req = mpt_get_request(mpt);
592 mpt_check_doorbell(mpt);
593 mpt_send_cmd(mpt, req);
597 mpt_intr(mpt);
599 mpt_prt(mpt, "read_cfg_header timed out");
604 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
606 mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x",
608 mpt_free_reply(mpt, (req->sequence << 1));
612 mpt_free_reply(mpt, (req->sequence << 1));
613 mpt_free_request(mpt, req);
620 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
629 req = mpt_get_request(mpt);
649 mpt_check_doorbell(mpt);
650 mpt_send_cmd(mpt, req);
654 mpt_intr(mpt);
656 mpt_prt(mpt, "read_cfg_page timed out");
661 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
663 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x",
665 mpt_free_reply(mpt, (req->sequence << 1));
668 mpt_free_reply(mpt, (req->sequence << 1));
670 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
690 mpt_free_request(mpt, req);
695 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
704 req = mpt_get_request(mpt);
712 mpt_prt(mpt, "page type 0x%x not changeable",
754 mpt_check_doorbell(mpt);
755 mpt_send_cmd(mpt, req);
759 mpt_intr(mpt);
762 mpt_prt(mpt, "mpt_write_cfg_page timed out");
767 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
769 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x",
771 mpt_free_reply(mpt, (req->sequence << 1));
774 mpt_free_reply(mpt, (req->sequence << 1));
776 mpt_free_request(mpt, req);
784 mpt_read_config_info_spi(mpt_softc_t *mpt)
788 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
789 0, &mpt->mpt_port_page0.Header);
793 if (mpt->verbose > 1) {
794 mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x",
795 mpt->mpt_port_page0.Header.PageVersion,
796 mpt->mpt_port_page0.Header.PageLength,
797 mpt->mpt_port_page0.Header.PageNumber,
798 mpt->mpt_port_page0.Header.PageType);
801 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
802 0, &mpt->mpt_port_page1.Header);
806 if (mpt->verbose > 1) {
807 mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x",
808 mpt->mpt_port_page1.Header.PageVersion,
809 mpt->mpt_port_page1.Header.PageLength,
810 mpt->mpt_port_page1.Header.PageNumber,
811 mpt->mpt_port_page1.Header.PageType);
814 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
815 0, &mpt->mpt_port_page2.Header);
820 if (mpt->verbose > 1) {
821 mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x",
822 mpt->mpt_port_page1.Header.PageVersion,
823 mpt->mpt_port_page1.Header.PageLength,
824 mpt->mpt_port_page1.Header.PageNumber,
825 mpt->mpt_port_page1.Header.PageType);
829 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
830 0, i, &mpt->mpt_dev_page0[i].Header);
834 if (mpt->verbose > 1) {
835 mpt_prt(mpt,
837 i, mpt->mpt_dev_page0[i].Header.PageVersion,
838 mpt->mpt_dev_page0[i].Header.PageLength,
839 mpt->mpt_dev_page0[i].Header.PageNumber,
840 mpt->mpt_dev_page0[i].Header.PageType);
843 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
844 1, i, &mpt->mpt_dev_page1[i].Header);
848 if (mpt->verbose > 1) {
849 mpt_prt(mpt,
851 i, mpt->mpt_dev_page1[i].Header.PageVersion,
852 mpt->mpt_dev_page1[i].Header.PageLength,
853 mpt->mpt_dev_page1[i].Header.PageNumber,
854 mpt->mpt_dev_page1[i].Header.PageType);
864 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
865 mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0);
867 mpt_prt(mpt, "failed to read SPI Port Page 0");
868 } else if (mpt->verbose > 1) {
869 mpt_prt(mpt,
871 mpt->mpt_port_page0.Capabilities,
872 mpt->mpt_port_page0.PhysicalInterface);
875 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
876 mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1);
878 mpt_prt(mpt, "failed to read SPI Port Page 1");
879 } else if (mpt->verbose > 1) {
880 mpt_prt(mpt,
882 mpt->mpt_port_page1.Configuration,
883 mpt->mpt_port_page1.OnBusTimerValue);
886 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
887 mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2);
889 mpt_prt(mpt, "failed to read SPI Port Page 2");
890 } else if (mpt->verbose > 1) {
891 mpt_prt(mpt,
893 mpt->mpt_port_page2.PortFlags,
894 mpt->mpt_port_page2.PortSettings);
896 mpt_prt(mpt,
898 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
899 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
900 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
905 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
906 mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]);
908 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i);
911 if (mpt->verbose > 1) {
912 mpt_prt(mpt,
914 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
915 mpt->mpt_dev_page0[i].Information);
917 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
918 mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]);
920 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i);
923 if (mpt->verbose > 1) {
924 mpt_prt(mpt,
926 i, mpt->mpt_dev_page1[i].RequestedParameters,
927 mpt->mpt_dev_page1[i].Configuration);
939 mpt_set_initial_config_spi(mpt_softc_t *mpt)
941 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
943 mpt->mpt_disc_enable = 0xffff;
944 mpt->mpt_tag_enable = 0;
946 if (mpt->mpt_port_page1.Configuration != pp1val) {
949 mpt_prt(mpt,
951 mpt->mpt_port_page1.Configuration, pp1val);
952 tmp = mpt->mpt_port_page1;
955 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
958 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
963 mpt_prt(mpt,
967 mpt->mpt_port_page1 = tmp;
974 tmp = mpt->mpt_dev_page1[i];
977 if (mpt->verbose > 1) {
978 mpt_prt(mpt,
983 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
986 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
990 mpt->mpt_dev_page1[i] = tmp;
991 if (mpt->verbose > 1) {
992 mpt_prt(mpt,
994 mpt->mpt_dev_page1[i].RequestedParameters,
995 mpt->mpt_dev_page1[i].Configuration);
1005 mpt_send_port_enable(mpt_softc_t *mpt, int port)
1011 req = mpt_get_request(mpt);
1020 mpt_check_doorbell(mpt);
1021 if (mpt->verbose > 1) {
1022 mpt_prt(mpt, "enabling port %d", port);
1024 mpt_send_cmd(mpt, req);
1029 mpt_intr(mpt);
1031 mpt_prt(mpt, "port enable timed out");
1035 mpt_free_request(mpt, req);
1046 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
1051 req = mpt_get_request(mpt);
1060 mpt_check_doorbell(mpt);
1061 if (mpt->verbose > 1) {
1062 mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis");
1064 mpt_send_cmd(mpt, req);
1073 mpt_enable_ints(mpt_softc_t *mpt)
1076 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1083 mpt_disable_ints(mpt_softc_t *mpt)
1086 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1092 mpt_hw_init(mpt_softc_t *mpt)
1102 db = mpt_rd_db(mpt);
1115 if (mpt_reset(mpt) != MPT_OK) {
1126 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1137 SLIST_INIT(&mpt->request_free_list);
1138 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1139 mpt_free_request(mpt, &mpt->request_pool[val]);
1142 if (mpt->verbose > 1) {
1143 mpt_prt(mpt, "doorbell req = %s",
1144 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1150 if (mpt_hw_init(mpt) != 0)
1153 dict = device_properties(mpt->sc_dev);
1160 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1161 mpt_prt(mpt, "mpt_get_iocfacts failed");
1166 if (mpt->verbose > 1) {
1167 mpt_prt(mpt,
1172 mpt->mpt_max_devices = facts.MaxDevices;
1173 mpt->mpt_global_credits = facts.GlobalCredits;
1174 mpt->request_frame_size = facts.RequestFrameSize;
1176 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1177 mpt_prt(mpt, "mpt_get_portfacts failed");
1182 if (mpt->verbose > 1) {
1183 mpt_prt(mpt,
1190 mpt_prt(mpt, "initiator role unsupported");
1196 mpt->is_fc = 1;
1197 mpt->mpt_max_devices = 255;
1200 mpt->is_scsi = 1;
1202 mpt->mpt_max_devices = 16;
1205 mpt->is_sas = 1;
1208 mpt_prt(mpt, "Unsupported Port Type (%x)",
1213 if (!mpt->is_sas && !mpt->is_fc &&
1215 mpt->mpt_ini_id = ini_id;
1217 mpt->mpt_ini_id = pfp.PortSCSIID;
1219 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1220 mpt_prt(mpt, "mpt_send_ioc_init failed");
1224 if (mpt->verbose > 1) {
1225 mpt_prt(mpt, "mpt_send_ioc_init ok");
1228 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1229 mpt_prt(mpt, "IOC failed to go to run state");
1232 if (mpt->verbose > 1) {
1233 mpt_prt(mpt, "IOC now at RUNSTATE");
1241 for (val = 0, pptr = mpt->reply_phys;
1242 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1244 mpt_free_reply(mpt, pptr);
1245 if (++val == mpt->mpt_global_credits - 1)
1252 mpt_send_event_request(mpt, 1);
1260 if (mpt->is_scsi) {
1261 if (mpt_read_config_info_spi(mpt)) {
1264 if (mpt_set_initial_config_spi(mpt)) {
1272 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1273 mpt_prt(mpt, "failed to enable port 0");
1277 if (mpt->verbose > 1) {
1278 mpt_prt(mpt, "enabled port 0");
1286 mpt_prt(mpt, "failed to initialize IOC");
1290 if (mpt->verbose > 1) {
1291 mpt_prt(mpt, "enabling interrupts");
1294 mpt_enable_ints(mpt);