mpt3sas_transport.c 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200
  1. /*
  2. * SAS Transport Layer for MPT (Message Passing Technology) based controllers
  3. *
  4. * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c
  5. * Copyright (C) 2012-2014 LSI Corporation
  6. * Copyright (C) 2013-2014 Avago Technologies
  7. * (mailto: [email protected])
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * NO WARRANTY
  20. * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  21. * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  22. * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  23. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  24. * solely responsible for determining the appropriateness of using and
  25. * distributing the Program and assumes all risks associated with its
  26. * exercise of rights under this Agreement, including but not limited to
  27. * the risks and costs of program errors, damage to or loss of data,
  28. * programs or equipment, and unavailability or interruption of operations.
  29. * DISCLAIMER OF LIABILITY
  30. * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  31. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  33. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  34. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  35. * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  36. * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  37. * You should have received a copy of the GNU General Public License
  38. * along with this program; if not, write to the Free Software
  39. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  40. * USA.
  41. */
  42. #include <linux/module.h>
  43. #include <linux/kernel.h>
  44. #include <linux/init.h>
  45. #include <linux/errno.h>
  46. #include <linux/sched.h>
  47. #include <linux/workqueue.h>
  48. #include <linux/delay.h>
  49. #include <linux/pci.h>
  50. #include <scsi/scsi.h>
  51. #include <scsi/scsi_cmnd.h>
  52. #include <scsi/scsi_device.h>
  53. #include <scsi/scsi_host.h>
  54. #include <scsi/scsi_transport_sas.h>
  55. #include <scsi/scsi_dbg.h>
  56. #include "mpt3sas_base.h"
  57. /**
  58. * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to
  59. * @phy: sas_phy object
  60. *
  61. * Return Port number
  62. */
  63. static inline u8
  64. _transport_get_port_id_by_sas_phy(struct sas_phy *phy)
  65. {
  66. u8 port_id = 0xFF;
  67. struct hba_port *port = phy->hostdata;
  68. if (port)
  69. port_id = port->port_id;
  70. return port_id;
  71. }
  72. /**
  73. * _transport_sas_node_find_by_sas_address - sas node search
  74. * @ioc: per adapter object
  75. * @sas_address: sas address of expander or sas host
  76. * @port: hba port entry
  77. * Context: Calling function should acquire ioc->sas_node_lock.
  78. *
  79. * Search for either hba phys or expander device based on handle, then returns
  80. * the sas_node object.
  81. */
  82. static struct _sas_node *
  83. _transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
  84. u64 sas_address, struct hba_port *port)
  85. {
  86. if (ioc->sas_hba.sas_address == sas_address)
  87. return &ioc->sas_hba;
  88. else
  89. return mpt3sas_scsih_expander_find_by_sas_address(ioc,
  90. sas_address, port);
  91. }
  92. /**
  93. * _transport_get_port_id_by_rphy - Get Port number from rphy object
  94. * @ioc: per adapter object
  95. * @rphy: sas_rphy object
  96. *
  97. * Returns Port number.
  98. */
  99. static u8
  100. _transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER *ioc,
  101. struct sas_rphy *rphy)
  102. {
  103. struct _sas_node *sas_expander;
  104. struct _sas_device *sas_device;
  105. unsigned long flags;
  106. u8 port_id = 0xFF;
  107. if (!rphy)
  108. return port_id;
  109. if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
  110. rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) {
  111. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  112. list_for_each_entry(sas_expander,
  113. &ioc->sas_expander_list, list) {
  114. if (sas_expander->rphy == rphy) {
  115. port_id = sas_expander->port->port_id;
  116. break;
  117. }
  118. }
  119. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  120. } else if (rphy->identify.device_type == SAS_END_DEVICE) {
  121. spin_lock_irqsave(&ioc->sas_device_lock, flags);
  122. sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
  123. if (sas_device) {
  124. port_id = sas_device->port->port_id;
  125. sas_device_put(sas_device);
  126. }
  127. spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
  128. }
  129. return port_id;
  130. }
  131. /**
  132. * _transport_convert_phy_link_rate -
  133. * @link_rate: link rate returned from mpt firmware
  134. *
  135. * Convert link_rate from mpi fusion into sas_transport form.
  136. */
  137. static enum sas_linkrate
  138. _transport_convert_phy_link_rate(u8 link_rate)
  139. {
  140. enum sas_linkrate rc;
  141. switch (link_rate) {
  142. case MPI2_SAS_NEG_LINK_RATE_1_5:
  143. rc = SAS_LINK_RATE_1_5_GBPS;
  144. break;
  145. case MPI2_SAS_NEG_LINK_RATE_3_0:
  146. rc = SAS_LINK_RATE_3_0_GBPS;
  147. break;
  148. case MPI2_SAS_NEG_LINK_RATE_6_0:
  149. rc = SAS_LINK_RATE_6_0_GBPS;
  150. break;
  151. case MPI25_SAS_NEG_LINK_RATE_12_0:
  152. rc = SAS_LINK_RATE_12_0_GBPS;
  153. break;
  154. case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
  155. rc = SAS_PHY_DISABLED;
  156. break;
  157. case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
  158. rc = SAS_LINK_RATE_FAILED;
  159. break;
  160. case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
  161. rc = SAS_SATA_PORT_SELECTOR;
  162. break;
  163. case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
  164. rc = SAS_PHY_RESET_IN_PROGRESS;
  165. break;
  166. default:
  167. case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
  168. case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
  169. rc = SAS_LINK_RATE_UNKNOWN;
  170. break;
  171. }
  172. return rc;
  173. }
  174. /**
  175. * _transport_set_identify - set identify for phys and end devices
  176. * @ioc: per adapter object
  177. * @handle: device handle
  178. * @identify: sas identify info
  179. *
  180. * Populates sas identify info.
  181. *
  182. * Return: 0 for success, non-zero for failure.
  183. */
  184. static int
  185. _transport_set_identify(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  186. struct sas_identify *identify)
  187. {
  188. Mpi2SasDevicePage0_t sas_device_pg0;
  189. Mpi2ConfigReply_t mpi_reply;
  190. u32 device_info;
  191. u32 ioc_status;
  192. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  193. ioc_info(ioc, "%s: host reset in progress!\n", __func__);
  194. return -EFAULT;
  195. }
  196. if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
  197. MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
  198. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  199. __FILE__, __LINE__, __func__);
  200. return -ENXIO;
  201. }
  202. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  203. MPI2_IOCSTATUS_MASK;
  204. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  205. ioc_err(ioc, "handle(0x%04x), ioc_status(0x%04x) failure at %s:%d/%s()!\n",
  206. handle, ioc_status, __FILE__, __LINE__, __func__);
  207. return -EIO;
  208. }
  209. memset(identify, 0, sizeof(struct sas_identify));
  210. device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
  211. /* sas_address */
  212. identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
  213. /* phy number of the parent device this device is linked to */
  214. identify->phy_identifier = sas_device_pg0.PhyNum;
  215. /* device_type */
  216. switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
  217. case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
  218. identify->device_type = SAS_PHY_UNUSED;
  219. break;
  220. case MPI2_SAS_DEVICE_INFO_END_DEVICE:
  221. identify->device_type = SAS_END_DEVICE;
  222. break;
  223. case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
  224. identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
  225. break;
  226. case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
  227. identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
  228. break;
  229. }
  230. /* initiator_port_protocols */
  231. if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
  232. identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
  233. if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
  234. identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
  235. if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
  236. identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
  237. if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
  238. identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
  239. /* target_port_protocols */
  240. if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
  241. identify->target_port_protocols |= SAS_PROTOCOL_SSP;
  242. if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
  243. identify->target_port_protocols |= SAS_PROTOCOL_STP;
  244. if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
  245. identify->target_port_protocols |= SAS_PROTOCOL_SMP;
  246. if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
  247. identify->target_port_protocols |= SAS_PROTOCOL_SATA;
  248. return 0;
  249. }
  250. /**
  251. * mpt3sas_transport_done - internal transport layer callback handler.
  252. * @ioc: per adapter object
  253. * @smid: system request message index
  254. * @msix_index: MSIX table index supplied by the OS
  255. * @reply: reply message frame(lower 32bit addr)
  256. *
  257. * Callback handler when sending internal generated transport cmds.
  258. * The callback index passed is `ioc->transport_cb_idx`
  259. *
  260. * Return: 1 meaning mf should be freed from _base_interrupt
  261. * 0 means the mf is freed from this function.
  262. */
  263. u8
  264. mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
  265. u32 reply)
  266. {
  267. MPI2DefaultReply_t *mpi_reply;
  268. mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
  269. if (ioc->transport_cmds.status == MPT3_CMD_NOT_USED)
  270. return 1;
  271. if (ioc->transport_cmds.smid != smid)
  272. return 1;
  273. ioc->transport_cmds.status |= MPT3_CMD_COMPLETE;
  274. if (mpi_reply) {
  275. memcpy(ioc->transport_cmds.reply, mpi_reply,
  276. mpi_reply->MsgLength*4);
  277. ioc->transport_cmds.status |= MPT3_CMD_REPLY_VALID;
  278. }
  279. ioc->transport_cmds.status &= ~MPT3_CMD_PENDING;
  280. complete(&ioc->transport_cmds.done);
  281. return 1;
  282. }
  283. /* report manufacture request structure */
  284. struct rep_manu_request {
  285. u8 smp_frame_type;
  286. u8 function;
  287. u8 reserved;
  288. u8 request_length;
  289. };
  290. /* report manufacture reply structure */
  291. struct rep_manu_reply {
  292. u8 smp_frame_type; /* 0x41 */
  293. u8 function; /* 0x01 */
  294. u8 function_result;
  295. u8 response_length;
  296. u16 expander_change_count;
  297. u8 reserved0[2];
  298. u8 sas_format;
  299. u8 reserved2[3];
  300. u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
  301. u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
  302. u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
  303. u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
  304. u16 component_id;
  305. u8 component_revision_id;
  306. u8 reserved3;
  307. u8 vendor_specific[8];
  308. };
  309. /**
  310. * _transport_expander_report_manufacture - obtain SMP report_manufacture
  311. * @ioc: per adapter object
  312. * @sas_address: expander sas address
  313. * @edev: the sas_expander_device object
  314. * @port_id: Port ID number
  315. *
  316. * Fills in the sas_expander_device object when SMP port is created.
  317. *
  318. * Return: 0 for success, non-zero for failure.
  319. */
  320. static int
  321. _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
  322. u64 sas_address, struct sas_expander_device *edev, u8 port_id)
  323. {
  324. Mpi2SmpPassthroughRequest_t *mpi_request;
  325. Mpi2SmpPassthroughReply_t *mpi_reply;
  326. struct rep_manu_reply *manufacture_reply;
  327. struct rep_manu_request *manufacture_request;
  328. int rc;
  329. u16 smid;
  330. void *psge;
  331. u8 issue_reset = 0;
  332. void *data_out = NULL;
  333. dma_addr_t data_out_dma;
  334. dma_addr_t data_in_dma;
  335. size_t data_in_sz;
  336. size_t data_out_sz;
  337. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  338. ioc_info(ioc, "%s: host reset in progress!\n", __func__);
  339. return -EFAULT;
  340. }
  341. mutex_lock(&ioc->transport_cmds.mutex);
  342. if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
  343. ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
  344. rc = -EAGAIN;
  345. goto out;
  346. }
  347. ioc->transport_cmds.status = MPT3_CMD_PENDING;
  348. rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
  349. if (rc)
  350. goto out;
  351. smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
  352. if (!smid) {
  353. ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
  354. rc = -EAGAIN;
  355. goto out;
  356. }
  357. rc = 0;
  358. mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
  359. ioc->transport_cmds.smid = smid;
  360. data_out_sz = sizeof(struct rep_manu_request);
  361. data_in_sz = sizeof(struct rep_manu_reply);
  362. data_out = dma_alloc_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz,
  363. &data_out_dma, GFP_KERNEL);
  364. if (!data_out) {
  365. pr_err("failure at %s:%d/%s()!\n", __FILE__,
  366. __LINE__, __func__);
  367. rc = -ENOMEM;
  368. mpt3sas_base_free_smid(ioc, smid);
  369. goto out;
  370. }
  371. data_in_dma = data_out_dma + sizeof(struct rep_manu_request);
  372. manufacture_request = data_out;
  373. manufacture_request->smp_frame_type = 0x40;
  374. manufacture_request->function = 1;
  375. manufacture_request->reserved = 0;
  376. manufacture_request->request_length = 0;
  377. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  378. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  379. mpi_request->PhysicalPort = port_id;
  380. mpi_request->SASAddress = cpu_to_le64(sas_address);
  381. mpi_request->RequestDataLength = cpu_to_le16(data_out_sz);
  382. psge = &mpi_request->SGL;
  383. ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
  384. data_in_sz);
  385. dtransportprintk(ioc,
  386. ioc_info(ioc, "report_manufacture - send to sas_addr(0x%016llx)\n",
  387. (u64)sas_address));
  388. init_completion(&ioc->transport_cmds.done);
  389. ioc->put_smid_default(ioc, smid);
  390. wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
  391. if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
  392. ioc_err(ioc, "%s: timeout\n", __func__);
  393. _debug_dump_mf(mpi_request,
  394. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  395. if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
  396. issue_reset = 1;
  397. goto issue_host_reset;
  398. }
  399. dtransportprintk(ioc, ioc_info(ioc, "report_manufacture - complete\n"));
  400. if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
  401. u8 *tmp;
  402. mpi_reply = ioc->transport_cmds.reply;
  403. dtransportprintk(ioc,
  404. ioc_info(ioc, "report_manufacture - reply data transfer size(%d)\n",
  405. le16_to_cpu(mpi_reply->ResponseDataLength)));
  406. if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
  407. sizeof(struct rep_manu_reply))
  408. goto out;
  409. manufacture_reply = data_out + sizeof(struct rep_manu_request);
  410. strncpy(edev->vendor_id, manufacture_reply->vendor_id,
  411. SAS_EXPANDER_VENDOR_ID_LEN);
  412. strncpy(edev->product_id, manufacture_reply->product_id,
  413. SAS_EXPANDER_PRODUCT_ID_LEN);
  414. strncpy(edev->product_rev, manufacture_reply->product_rev,
  415. SAS_EXPANDER_PRODUCT_REV_LEN);
  416. edev->level = manufacture_reply->sas_format & 1;
  417. if (edev->level) {
  418. strncpy(edev->component_vendor_id,
  419. manufacture_reply->component_vendor_id,
  420. SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
  421. tmp = (u8 *)&manufacture_reply->component_id;
  422. edev->component_id = tmp[0] << 8 | tmp[1];
  423. edev->component_revision_id =
  424. manufacture_reply->component_revision_id;
  425. }
  426. } else
  427. dtransportprintk(ioc,
  428. ioc_info(ioc, "report_manufacture - no reply\n"));
  429. issue_host_reset:
  430. if (issue_reset)
  431. mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
  432. out:
  433. ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
  434. if (data_out)
  435. dma_free_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz,
  436. data_out, data_out_dma);
  437. mutex_unlock(&ioc->transport_cmds.mutex);
  438. return rc;
  439. }
  440. /**
  441. * _transport_delete_port - helper function to removing a port
  442. * @ioc: per adapter object
  443. * @mpt3sas_port: mpt3sas per port object
  444. */
  445. static void
  446. _transport_delete_port(struct MPT3SAS_ADAPTER *ioc,
  447. struct _sas_port *mpt3sas_port)
  448. {
  449. u64 sas_address = mpt3sas_port->remote_identify.sas_address;
  450. struct hba_port *port = mpt3sas_port->hba_port;
  451. enum sas_device_type device_type =
  452. mpt3sas_port->remote_identify.device_type;
  453. dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
  454. "remove: sas_addr(0x%016llx)\n",
  455. (unsigned long long) sas_address);
  456. ioc->logging_level |= MPT_DEBUG_TRANSPORT;
  457. if (device_type == SAS_END_DEVICE)
  458. mpt3sas_device_remove_by_sas_address(ioc,
  459. sas_address, port);
  460. else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
  461. device_type == SAS_FANOUT_EXPANDER_DEVICE)
  462. mpt3sas_expander_remove(ioc, sas_address, port);
  463. ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
  464. }
  465. /**
  466. * _transport_delete_phy - helper function to removing single phy from port
  467. * @ioc: per adapter object
  468. * @mpt3sas_port: mpt3sas per port object
  469. * @mpt3sas_phy: mpt3sas per phy object
  470. */
  471. static void
  472. _transport_delete_phy(struct MPT3SAS_ADAPTER *ioc,
  473. struct _sas_port *mpt3sas_port, struct _sas_phy *mpt3sas_phy)
  474. {
  475. u64 sas_address = mpt3sas_port->remote_identify.sas_address;
  476. dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
  477. "remove: sas_addr(0x%016llx), phy(%d)\n",
  478. (unsigned long long) sas_address, mpt3sas_phy->phy_id);
  479. list_del(&mpt3sas_phy->port_siblings);
  480. mpt3sas_port->num_phys--;
  481. sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
  482. mpt3sas_phy->phy_belongs_to_port = 0;
  483. }
  484. /**
  485. * _transport_add_phy - helper function to adding single phy to port
  486. * @ioc: per adapter object
  487. * @mpt3sas_port: mpt3sas per port object
  488. * @mpt3sas_phy: mpt3sas per phy object
  489. */
  490. static void
  491. _transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt3sas_port,
  492. struct _sas_phy *mpt3sas_phy)
  493. {
  494. u64 sas_address = mpt3sas_port->remote_identify.sas_address;
  495. dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
  496. "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
  497. sas_address, mpt3sas_phy->phy_id);
  498. list_add_tail(&mpt3sas_phy->port_siblings, &mpt3sas_port->phy_list);
  499. mpt3sas_port->num_phys++;
  500. sas_port_add_phy(mpt3sas_port->port, mpt3sas_phy->phy);
  501. mpt3sas_phy->phy_belongs_to_port = 1;
  502. }
  503. /**
  504. * mpt3sas_transport_add_phy_to_an_existing_port - adding new phy to existing port
  505. * @ioc: per adapter object
  506. * @sas_node: sas node object (either expander or sas host)
  507. * @mpt3sas_phy: mpt3sas per phy object
  508. * @sas_address: sas address of device/expander were phy needs to be added to
  509. * @port: hba port entry
  510. */
  511. void
  512. mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
  513. struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy,
  514. u64 sas_address, struct hba_port *port)
  515. {
  516. struct _sas_port *mpt3sas_port;
  517. struct _sas_phy *phy_srch;
  518. if (mpt3sas_phy->phy_belongs_to_port == 1)
  519. return;
  520. if (!port)
  521. return;
  522. list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list,
  523. port_list) {
  524. if (mpt3sas_port->remote_identify.sas_address !=
  525. sas_address)
  526. continue;
  527. if (mpt3sas_port->hba_port != port)
  528. continue;
  529. list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
  530. port_siblings) {
  531. if (phy_srch == mpt3sas_phy)
  532. return;
  533. }
  534. _transport_add_phy(ioc, mpt3sas_port, mpt3sas_phy);
  535. return;
  536. }
  537. }
  538. /**
  539. * mpt3sas_transport_del_phy_from_an_existing_port - delete phy from existing port
  540. * @ioc: per adapter object
  541. * @sas_node: sas node object (either expander or sas host)
  542. * @mpt3sas_phy: mpt3sas per phy object
  543. */
  544. void
  545. mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
  546. struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy)
  547. {
  548. struct _sas_port *mpt3sas_port, *next;
  549. struct _sas_phy *phy_srch;
  550. if (mpt3sas_phy->phy_belongs_to_port == 0)
  551. return;
  552. list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
  553. port_list) {
  554. list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
  555. port_siblings) {
  556. if (phy_srch != mpt3sas_phy)
  557. continue;
  558. /*
  559. * Don't delete port during host reset,
  560. * just delete phy.
  561. */
  562. if (mpt3sas_port->num_phys == 1 && !ioc->shost_recovery)
  563. _transport_delete_port(ioc, mpt3sas_port);
  564. else
  565. _transport_delete_phy(ioc, mpt3sas_port,
  566. mpt3sas_phy);
  567. return;
  568. }
  569. }
  570. }
  571. /**
  572. * _transport_sanity_check - sanity check when adding a new port
  573. * @ioc: per adapter object
  574. * @sas_node: sas node object (either expander or sas host)
  575. * @sas_address: sas address of device being added
  576. * @port: hba port entry
  577. *
  578. * See the explanation above from _transport_delete_duplicate_port
  579. */
  580. static void
  581. _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node,
  582. u64 sas_address, struct hba_port *port)
  583. {
  584. int i;
  585. for (i = 0; i < sas_node->num_phys; i++) {
  586. if (sas_node->phy[i].remote_identify.sas_address != sas_address)
  587. continue;
  588. if (sas_node->phy[i].port != port)
  589. continue;
  590. if (sas_node->phy[i].phy_belongs_to_port == 1)
  591. mpt3sas_transport_del_phy_from_an_existing_port(ioc,
  592. sas_node, &sas_node->phy[i]);
  593. }
  594. }
  595. /**
  596. * mpt3sas_transport_port_add - insert port to the list
  597. * @ioc: per adapter object
  598. * @handle: handle of attached device
  599. * @sas_address: sas address of parent expander or sas host
  600. * @hba_port: hba port entry
  601. * Context: This function will acquire ioc->sas_node_lock.
  602. *
  603. * Adding new port object to the sas_node->sas_port_list.
  604. *
  605. * Return: mpt3sas_port.
  606. */
  607. struct _sas_port *
  608. mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  609. u64 sas_address, struct hba_port *hba_port)
  610. {
  611. struct _sas_phy *mpt3sas_phy, *next;
  612. struct _sas_port *mpt3sas_port;
  613. unsigned long flags;
  614. struct _sas_node *sas_node;
  615. struct sas_rphy *rphy;
  616. struct _sas_device *sas_device = NULL;
  617. int i;
  618. struct sas_port *port;
  619. struct virtual_phy *vphy = NULL;
  620. if (!hba_port) {
  621. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  622. __FILE__, __LINE__, __func__);
  623. return NULL;
  624. }
  625. mpt3sas_port = kzalloc(sizeof(struct _sas_port),
  626. GFP_KERNEL);
  627. if (!mpt3sas_port) {
  628. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  629. __FILE__, __LINE__, __func__);
  630. return NULL;
  631. }
  632. INIT_LIST_HEAD(&mpt3sas_port->port_list);
  633. INIT_LIST_HEAD(&mpt3sas_port->phy_list);
  634. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  635. sas_node = _transport_sas_node_find_by_sas_address(ioc,
  636. sas_address, hba_port);
  637. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  638. if (!sas_node) {
  639. ioc_err(ioc, "%s: Could not find parent sas_address(0x%016llx)!\n",
  640. __func__, (u64)sas_address);
  641. goto out_fail;
  642. }
  643. if ((_transport_set_identify(ioc, handle,
  644. &mpt3sas_port->remote_identify))) {
  645. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  646. __FILE__, __LINE__, __func__);
  647. goto out_fail;
  648. }
  649. if (mpt3sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
  650. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  651. __FILE__, __LINE__, __func__);
  652. goto out_fail;
  653. }
  654. mpt3sas_port->hba_port = hba_port;
  655. _transport_sanity_check(ioc, sas_node,
  656. mpt3sas_port->remote_identify.sas_address, hba_port);
  657. for (i = 0; i < sas_node->num_phys; i++) {
  658. if (sas_node->phy[i].remote_identify.sas_address !=
  659. mpt3sas_port->remote_identify.sas_address)
  660. continue;
  661. if (sas_node->phy[i].port != hba_port)
  662. continue;
  663. list_add_tail(&sas_node->phy[i].port_siblings,
  664. &mpt3sas_port->phy_list);
  665. mpt3sas_port->num_phys++;
  666. if (sas_node->handle <= ioc->sas_hba.num_phys) {
  667. if (!sas_node->phy[i].hba_vphy) {
  668. hba_port->phy_mask |= (1 << i);
  669. continue;
  670. }
  671. vphy = mpt3sas_get_vphy_by_phy(ioc, hba_port, i);
  672. if (!vphy) {
  673. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  674. __FILE__, __LINE__, __func__);
  675. goto out_fail;
  676. }
  677. }
  678. }
  679. if (!mpt3sas_port->num_phys) {
  680. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  681. __FILE__, __LINE__, __func__);
  682. goto out_fail;
  683. }
  684. if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
  685. sas_device = mpt3sas_get_sdev_by_addr(ioc,
  686. mpt3sas_port->remote_identify.sas_address,
  687. mpt3sas_port->hba_port);
  688. if (!sas_device) {
  689. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  690. __FILE__, __LINE__, __func__);
  691. goto out_fail;
  692. }
  693. sas_device->pend_sas_rphy_add = 1;
  694. }
  695. if (!sas_node->parent_dev) {
  696. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  697. __FILE__, __LINE__, __func__);
  698. goto out_fail;
  699. }
  700. port = sas_port_alloc_num(sas_node->parent_dev);
  701. if (!port || (sas_port_add(port))) {
  702. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  703. __FILE__, __LINE__, __func__);
  704. goto out_fail;
  705. }
  706. list_for_each_entry(mpt3sas_phy, &mpt3sas_port->phy_list,
  707. port_siblings) {
  708. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  709. dev_printk(KERN_INFO, &port->dev,
  710. "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n",
  711. handle, (unsigned long long)
  712. mpt3sas_port->remote_identify.sas_address,
  713. mpt3sas_phy->phy_id);
  714. sas_port_add_phy(port, mpt3sas_phy->phy);
  715. mpt3sas_phy->phy_belongs_to_port = 1;
  716. mpt3sas_phy->port = hba_port;
  717. }
  718. mpt3sas_port->port = port;
  719. if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
  720. rphy = sas_end_device_alloc(port);
  721. sas_device->rphy = rphy;
  722. if (sas_node->handle <= ioc->sas_hba.num_phys) {
  723. if (!vphy)
  724. hba_port->sas_address =
  725. sas_device->sas_address;
  726. else
  727. vphy->sas_address =
  728. sas_device->sas_address;
  729. }
  730. } else {
  731. rphy = sas_expander_alloc(port,
  732. mpt3sas_port->remote_identify.device_type);
  733. if (sas_node->handle <= ioc->sas_hba.num_phys)
  734. hba_port->sas_address =
  735. mpt3sas_port->remote_identify.sas_address;
  736. }
  737. if (!rphy) {
  738. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  739. __FILE__, __LINE__, __func__);
  740. goto out_delete_port;
  741. }
  742. rphy->identify = mpt3sas_port->remote_identify;
  743. if ((sas_rphy_add(rphy))) {
  744. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  745. __FILE__, __LINE__, __func__);
  746. sas_rphy_free(rphy);
  747. rphy = NULL;
  748. goto out_delete_port;
  749. }
  750. if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
  751. sas_device->pend_sas_rphy_add = 0;
  752. sas_device_put(sas_device);
  753. }
  754. dev_info(&rphy->dev,
  755. "add: handle(0x%04x), sas_addr(0x%016llx)\n", handle,
  756. (unsigned long long)mpt3sas_port->remote_identify.sas_address);
  757. mpt3sas_port->rphy = rphy;
  758. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  759. list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list);
  760. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  761. /* fill in report manufacture */
  762. if (mpt3sas_port->remote_identify.device_type ==
  763. MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
  764. mpt3sas_port->remote_identify.device_type ==
  765. MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
  766. _transport_expander_report_manufacture(ioc,
  767. mpt3sas_port->remote_identify.sas_address,
  768. rphy_to_expander_device(rphy), hba_port->port_id);
  769. return mpt3sas_port;
  770. out_delete_port:
  771. sas_port_delete(port);
  772. out_fail:
  773. list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list,
  774. port_siblings)
  775. list_del(&mpt3sas_phy->port_siblings);
  776. kfree(mpt3sas_port);
  777. return NULL;
  778. }
  779. /**
  780. * mpt3sas_transport_port_remove - remove port from the list
  781. * @ioc: per adapter object
  782. * @sas_address: sas address of attached device
  783. * @sas_address_parent: sas address of parent expander or sas host
  784. * @port: hba port entry
  785. * Context: This function will acquire ioc->sas_node_lock.
  786. *
  787. * Removing object and freeing associated memory from the
  788. * ioc->sas_port_list.
  789. */
  790. void
  791. mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
  792. u64 sas_address_parent, struct hba_port *port)
  793. {
  794. int i;
  795. unsigned long flags;
  796. struct _sas_port *mpt3sas_port, *next;
  797. struct _sas_node *sas_node;
  798. u8 found = 0;
  799. struct _sas_phy *mpt3sas_phy, *next_phy;
  800. struct hba_port *hba_port_next, *hba_port = NULL;
  801. struct virtual_phy *vphy, *vphy_next = NULL;
  802. if (!port)
  803. return;
  804. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  805. sas_node = _transport_sas_node_find_by_sas_address(ioc,
  806. sas_address_parent, port);
  807. if (!sas_node) {
  808. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  809. return;
  810. }
  811. list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
  812. port_list) {
  813. if (mpt3sas_port->remote_identify.sas_address != sas_address)
  814. continue;
  815. if (mpt3sas_port->hba_port != port)
  816. continue;
  817. found = 1;
  818. list_del(&mpt3sas_port->port_list);
  819. goto out;
  820. }
  821. out:
  822. if (!found) {
  823. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  824. return;
  825. }
  826. if (sas_node->handle <= ioc->sas_hba.num_phys &&
  827. (ioc->multipath_on_hba)) {
  828. if (port->vphys_mask) {
  829. list_for_each_entry_safe(vphy, vphy_next,
  830. &port->vphys_list, list) {
  831. if (vphy->sas_address != sas_address)
  832. continue;
  833. ioc_info(ioc,
  834. "remove vphy entry: %p of port:%p,from %d port's vphys list\n",
  835. vphy, port, port->port_id);
  836. port->vphys_mask &= ~vphy->phy_mask;
  837. list_del(&vphy->list);
  838. kfree(vphy);
  839. }
  840. }
  841. list_for_each_entry_safe(hba_port, hba_port_next,
  842. &ioc->port_table_list, list) {
  843. if (hba_port != port)
  844. continue;
  845. /*
  846. * Delete hba_port object if
  847. * - hba_port object's sas address matches with current
  848. * removed device's sas address and no vphy's
  849. * associated with it.
  850. * - Current removed device is a vSES device and
  851. * none of the other direct attached device have
  852. * this vSES device's port number (hence hba_port
  853. * object sas_address field will be zero).
  854. */
  855. if ((hba_port->sas_address == sas_address ||
  856. !hba_port->sas_address) && !hba_port->vphys_mask) {
  857. ioc_info(ioc,
  858. "remove hba_port entry: %p port: %d from hba_port list\n",
  859. hba_port, hba_port->port_id);
  860. list_del(&hba_port->list);
  861. kfree(hba_port);
  862. } else if (hba_port->sas_address == sas_address &&
  863. hba_port->vphys_mask) {
  864. /*
  865. * Current removed device is a non vSES device
  866. * and a vSES device has the same port number
  867. * as of current device's port number. Hence
  868. * only clear the sas_address filed, don't
  869. * delete the hba_port object.
  870. */
  871. ioc_info(ioc,
  872. "clearing sas_address from hba_port entry: %p port: %d from hba_port list\n",
  873. hba_port, hba_port->port_id);
  874. port->sas_address = 0;
  875. }
  876. break;
  877. }
  878. }
  879. for (i = 0; i < sas_node->num_phys; i++) {
  880. if (sas_node->phy[i].remote_identify.sas_address == sas_address)
  881. memset(&sas_node->phy[i].remote_identify, 0 ,
  882. sizeof(struct sas_identify));
  883. }
  884. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  885. list_for_each_entry_safe(mpt3sas_phy, next_phy,
  886. &mpt3sas_port->phy_list, port_siblings) {
  887. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  888. dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
  889. "remove: sas_addr(0x%016llx), phy(%d)\n",
  890. (unsigned long long)
  891. mpt3sas_port->remote_identify.sas_address,
  892. mpt3sas_phy->phy_id);
  893. mpt3sas_phy->phy_belongs_to_port = 0;
  894. if (!ioc->remove_host)
  895. sas_port_delete_phy(mpt3sas_port->port,
  896. mpt3sas_phy->phy);
  897. list_del(&mpt3sas_phy->port_siblings);
  898. }
  899. if (!ioc->remove_host)
  900. sas_port_delete(mpt3sas_port->port);
  901. ioc_info(ioc, "%s: removed: sas_addr(0x%016llx)\n",
  902. __func__, (unsigned long long)sas_address);
  903. kfree(mpt3sas_port);
  904. }
  905. /**
  906. * mpt3sas_transport_add_host_phy - report sas_host phy to transport
  907. * @ioc: per adapter object
  908. * @mpt3sas_phy: mpt3sas per phy object
  909. * @phy_pg0: sas phy page 0
  910. * @parent_dev: parent device class object
  911. *
  912. * Return: 0 for success, non-zero for failure.
  913. */
  914. int
  915. mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
  916. *mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
  917. {
  918. struct sas_phy *phy;
  919. int phy_index = mpt3sas_phy->phy_id;
  920. INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
  921. phy = sas_phy_alloc(parent_dev, phy_index);
  922. if (!phy) {
  923. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  924. __FILE__, __LINE__, __func__);
  925. return -1;
  926. }
  927. if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
  928. &mpt3sas_phy->identify))) {
  929. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  930. __FILE__, __LINE__, __func__);
  931. sas_phy_free(phy);
  932. return -1;
  933. }
  934. phy->identify = mpt3sas_phy->identify;
  935. mpt3sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
  936. if (mpt3sas_phy->attached_handle)
  937. _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
  938. &mpt3sas_phy->remote_identify);
  939. phy->identify.phy_identifier = mpt3sas_phy->phy_id;
  940. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  941. phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  942. phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
  943. phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
  944. phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
  945. phy_pg0.HwLinkRate >> 4);
  946. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  947. phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  948. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  949. phy_pg0.ProgrammedLinkRate >> 4);
  950. phy->hostdata = mpt3sas_phy->port;
  951. if ((sas_phy_add(phy))) {
  952. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  953. __FILE__, __LINE__, __func__);
  954. sas_phy_free(phy);
  955. return -1;
  956. }
  957. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  958. dev_printk(KERN_INFO, &phy->dev,
  959. "add: handle(0x%04x), sas_addr(0x%016llx)\n"
  960. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  961. mpt3sas_phy->handle, (unsigned long long)
  962. mpt3sas_phy->identify.sas_address,
  963. mpt3sas_phy->attached_handle,
  964. (unsigned long long)
  965. mpt3sas_phy->remote_identify.sas_address);
  966. mpt3sas_phy->phy = phy;
  967. return 0;
  968. }
  969. /**
  970. * mpt3sas_transport_add_expander_phy - report expander phy to transport
  971. * @ioc: per adapter object
  972. * @mpt3sas_phy: mpt3sas per phy object
  973. * @expander_pg1: expander page 1
  974. * @parent_dev: parent device class object
  975. *
  976. * Return: 0 for success, non-zero for failure.
  977. */
  978. int
  979. mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
  980. *mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1,
  981. struct device *parent_dev)
  982. {
  983. struct sas_phy *phy;
  984. int phy_index = mpt3sas_phy->phy_id;
  985. INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
  986. phy = sas_phy_alloc(parent_dev, phy_index);
  987. if (!phy) {
  988. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  989. __FILE__, __LINE__, __func__);
  990. return -1;
  991. }
  992. if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
  993. &mpt3sas_phy->identify))) {
  994. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  995. __FILE__, __LINE__, __func__);
  996. sas_phy_free(phy);
  997. return -1;
  998. }
  999. phy->identify = mpt3sas_phy->identify;
  1000. mpt3sas_phy->attached_handle =
  1001. le16_to_cpu(expander_pg1.AttachedDevHandle);
  1002. if (mpt3sas_phy->attached_handle)
  1003. _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
  1004. &mpt3sas_phy->remote_identify);
  1005. phy->identify.phy_identifier = mpt3sas_phy->phy_id;
  1006. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  1007. expander_pg1.NegotiatedLinkRate &
  1008. MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  1009. phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
  1010. expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
  1011. phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
  1012. expander_pg1.HwLinkRate >> 4);
  1013. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  1014. expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  1015. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  1016. expander_pg1.ProgrammedLinkRate >> 4);
  1017. phy->hostdata = mpt3sas_phy->port;
  1018. if ((sas_phy_add(phy))) {
  1019. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1020. __FILE__, __LINE__, __func__);
  1021. sas_phy_free(phy);
  1022. return -1;
  1023. }
  1024. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  1025. dev_printk(KERN_INFO, &phy->dev,
  1026. "add: handle(0x%04x), sas_addr(0x%016llx)\n"
  1027. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  1028. mpt3sas_phy->handle, (unsigned long long)
  1029. mpt3sas_phy->identify.sas_address,
  1030. mpt3sas_phy->attached_handle,
  1031. (unsigned long long)
  1032. mpt3sas_phy->remote_identify.sas_address);
  1033. mpt3sas_phy->phy = phy;
  1034. return 0;
  1035. }
  1036. /**
  1037. * mpt3sas_transport_update_links - refreshing phy link changes
  1038. * @ioc: per adapter object
  1039. * @sas_address: sas address of parent expander or sas host
  1040. * @handle: attached device handle
  1041. * @phy_number: phy number
  1042. * @link_rate: new link rate
  1043. * @port: hba port entry
  1044. *
  1045. * Return nothing.
  1046. */
  1047. void
  1048. mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc,
  1049. u64 sas_address, u16 handle, u8 phy_number, u8 link_rate,
  1050. struct hba_port *port)
  1051. {
  1052. unsigned long flags;
  1053. struct _sas_node *sas_node;
  1054. struct _sas_phy *mpt3sas_phy;
  1055. struct hba_port *hba_port = NULL;
  1056. if (ioc->shost_recovery || ioc->pci_error_recovery)
  1057. return;
  1058. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  1059. sas_node = _transport_sas_node_find_by_sas_address(ioc,
  1060. sas_address, port);
  1061. if (!sas_node) {
  1062. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1063. return;
  1064. }
  1065. mpt3sas_phy = &sas_node->phy[phy_number];
  1066. mpt3sas_phy->attached_handle = handle;
  1067. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1068. if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
  1069. _transport_set_identify(ioc, handle,
  1070. &mpt3sas_phy->remote_identify);
  1071. if ((sas_node->handle <= ioc->sas_hba.num_phys) &&
  1072. (ioc->multipath_on_hba)) {
  1073. list_for_each_entry(hba_port,
  1074. &ioc->port_table_list, list) {
  1075. if (hba_port->sas_address == sas_address &&
  1076. hba_port == port)
  1077. hba_port->phy_mask |=
  1078. (1 << mpt3sas_phy->phy_id);
  1079. }
  1080. }
  1081. mpt3sas_transport_add_phy_to_an_existing_port(ioc, sas_node,
  1082. mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address,
  1083. port);
  1084. } else
  1085. memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct
  1086. sas_identify));
  1087. if (mpt3sas_phy->phy)
  1088. mpt3sas_phy->phy->negotiated_linkrate =
  1089. _transport_convert_phy_link_rate(link_rate);
  1090. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  1091. dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
  1092. "refresh: parent sas_addr(0x%016llx),\n"
  1093. "\tlink_rate(0x%02x), phy(%d)\n"
  1094. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  1095. (unsigned long long)sas_address,
  1096. link_rate, phy_number, handle, (unsigned long long)
  1097. mpt3sas_phy->remote_identify.sas_address);
  1098. }
  1099. static inline void *
  1100. phy_to_ioc(struct sas_phy *phy)
  1101. {
  1102. struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
  1103. return shost_priv(shost);
  1104. }
  1105. static inline void *
  1106. rphy_to_ioc(struct sas_rphy *rphy)
  1107. {
  1108. struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
  1109. return shost_priv(shost);
  1110. }
  1111. /* report phy error log structure */
  1112. struct phy_error_log_request {
  1113. u8 smp_frame_type; /* 0x40 */
  1114. u8 function; /* 0x11 */
  1115. u8 allocated_response_length;
  1116. u8 request_length; /* 02 */
  1117. u8 reserved_1[5];
  1118. u8 phy_identifier;
  1119. u8 reserved_2[2];
  1120. };
  1121. /* report phy error log reply structure */
  1122. struct phy_error_log_reply {
  1123. u8 smp_frame_type; /* 0x41 */
  1124. u8 function; /* 0x11 */
  1125. u8 function_result;
  1126. u8 response_length;
  1127. __be16 expander_change_count;
  1128. u8 reserved_1[3];
  1129. u8 phy_identifier;
  1130. u8 reserved_2[2];
  1131. __be32 invalid_dword;
  1132. __be32 running_disparity_error;
  1133. __be32 loss_of_dword_sync;
  1134. __be32 phy_reset_problem;
  1135. };
  1136. /**
  1137. * _transport_get_expander_phy_error_log - return expander counters
  1138. * @ioc: per adapter object
  1139. * @phy: The sas phy object
  1140. *
  1141. * Return: 0 for success, non-zero for failure.
  1142. *
  1143. */
  1144. static int
  1145. _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
  1146. struct sas_phy *phy)
  1147. {
  1148. Mpi2SmpPassthroughRequest_t *mpi_request;
  1149. Mpi2SmpPassthroughReply_t *mpi_reply;
  1150. struct phy_error_log_request *phy_error_log_request;
  1151. struct phy_error_log_reply *phy_error_log_reply;
  1152. int rc;
  1153. u16 smid;
  1154. void *psge;
  1155. u8 issue_reset = 0;
  1156. void *data_out = NULL;
  1157. dma_addr_t data_out_dma;
  1158. u32 sz;
  1159. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  1160. ioc_info(ioc, "%s: host reset in progress!\n", __func__);
  1161. return -EFAULT;
  1162. }
  1163. mutex_lock(&ioc->transport_cmds.mutex);
  1164. if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
  1165. ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
  1166. rc = -EAGAIN;
  1167. goto out;
  1168. }
  1169. ioc->transport_cmds.status = MPT3_CMD_PENDING;
  1170. rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
  1171. if (rc)
  1172. goto out;
  1173. smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
  1174. if (!smid) {
  1175. ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
  1176. rc = -EAGAIN;
  1177. goto out;
  1178. }
  1179. mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
  1180. ioc->transport_cmds.smid = smid;
  1181. sz = sizeof(struct phy_error_log_request) +
  1182. sizeof(struct phy_error_log_reply);
  1183. data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma,
  1184. GFP_KERNEL);
  1185. if (!data_out) {
  1186. pr_err("failure at %s:%d/%s()!\n", __FILE__,
  1187. __LINE__, __func__);
  1188. rc = -ENOMEM;
  1189. mpt3sas_base_free_smid(ioc, smid);
  1190. goto out;
  1191. }
  1192. rc = -EINVAL;
  1193. memset(data_out, 0, sz);
  1194. phy_error_log_request = data_out;
  1195. phy_error_log_request->smp_frame_type = 0x40;
  1196. phy_error_log_request->function = 0x11;
  1197. phy_error_log_request->request_length = 2;
  1198. phy_error_log_request->allocated_response_length = 0;
  1199. phy_error_log_request->phy_identifier = phy->number;
  1200. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  1201. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  1202. mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
  1203. mpi_request->VF_ID = 0; /* TODO */
  1204. mpi_request->VP_ID = 0;
  1205. mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
  1206. mpi_request->RequestDataLength =
  1207. cpu_to_le16(sizeof(struct phy_error_log_request));
  1208. psge = &mpi_request->SGL;
  1209. ioc->build_sg(ioc, psge, data_out_dma,
  1210. sizeof(struct phy_error_log_request),
  1211. data_out_dma + sizeof(struct phy_error_log_request),
  1212. sizeof(struct phy_error_log_reply));
  1213. dtransportprintk(ioc,
  1214. ioc_info(ioc, "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n",
  1215. (u64)phy->identify.sas_address,
  1216. phy->number));
  1217. init_completion(&ioc->transport_cmds.done);
  1218. ioc->put_smid_default(ioc, smid);
  1219. wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
  1220. if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
  1221. ioc_err(ioc, "%s: timeout\n", __func__);
  1222. _debug_dump_mf(mpi_request,
  1223. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  1224. if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
  1225. issue_reset = 1;
  1226. goto issue_host_reset;
  1227. }
  1228. dtransportprintk(ioc, ioc_info(ioc, "phy_error_log - complete\n"));
  1229. if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
  1230. mpi_reply = ioc->transport_cmds.reply;
  1231. dtransportprintk(ioc,
  1232. ioc_info(ioc, "phy_error_log - reply data transfer size(%d)\n",
  1233. le16_to_cpu(mpi_reply->ResponseDataLength)));
  1234. if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
  1235. sizeof(struct phy_error_log_reply))
  1236. goto out;
  1237. phy_error_log_reply = data_out +
  1238. sizeof(struct phy_error_log_request);
  1239. dtransportprintk(ioc,
  1240. ioc_info(ioc, "phy_error_log - function_result(%d)\n",
  1241. phy_error_log_reply->function_result));
  1242. phy->invalid_dword_count =
  1243. be32_to_cpu(phy_error_log_reply->invalid_dword);
  1244. phy->running_disparity_error_count =
  1245. be32_to_cpu(phy_error_log_reply->running_disparity_error);
  1246. phy->loss_of_dword_sync_count =
  1247. be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
  1248. phy->phy_reset_problem_count =
  1249. be32_to_cpu(phy_error_log_reply->phy_reset_problem);
  1250. rc = 0;
  1251. } else
  1252. dtransportprintk(ioc,
  1253. ioc_info(ioc, "phy_error_log - no reply\n"));
  1254. issue_host_reset:
  1255. if (issue_reset)
  1256. mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
  1257. out:
  1258. ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
  1259. if (data_out)
  1260. dma_free_coherent(&ioc->pdev->dev, sz, data_out, data_out_dma);
  1261. mutex_unlock(&ioc->transport_cmds.mutex);
  1262. return rc;
  1263. }
  1264. /**
  1265. * _transport_get_linkerrors - return phy counters for both hba and expanders
  1266. * @phy: The sas phy object
  1267. *
  1268. * Return: 0 for success, non-zero for failure.
  1269. *
  1270. */
  1271. static int
  1272. _transport_get_linkerrors(struct sas_phy *phy)
  1273. {
  1274. struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
  1275. unsigned long flags;
  1276. Mpi2ConfigReply_t mpi_reply;
  1277. Mpi2SasPhyPage1_t phy_pg1;
  1278. struct hba_port *port = phy->hostdata;
  1279. int port_id = port->port_id;
  1280. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  1281. if (_transport_sas_node_find_by_sas_address(ioc,
  1282. phy->identify.sas_address,
  1283. mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
  1284. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1285. return -EINVAL;
  1286. }
  1287. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1288. if (phy->identify.sas_address != ioc->sas_hba.sas_address)
  1289. return _transport_get_expander_phy_error_log(ioc, phy);
  1290. /* get hba phy error logs */
  1291. if ((mpt3sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
  1292. phy->number))) {
  1293. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1294. __FILE__, __LINE__, __func__);
  1295. return -ENXIO;
  1296. }
  1297. if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
  1298. ioc_info(ioc, "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n",
  1299. phy->number,
  1300. le16_to_cpu(mpi_reply.IOCStatus),
  1301. le32_to_cpu(mpi_reply.IOCLogInfo));
  1302. phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
  1303. phy->running_disparity_error_count =
  1304. le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
  1305. phy->loss_of_dword_sync_count =
  1306. le32_to_cpu(phy_pg1.LossDwordSynchCount);
  1307. phy->phy_reset_problem_count =
  1308. le32_to_cpu(phy_pg1.PhyResetProblemCount);
  1309. return 0;
  1310. }
  1311. /**
  1312. * _transport_get_enclosure_identifier -
  1313. * @rphy: The sas phy object
  1314. * @identifier: ?
  1315. *
  1316. * Obtain the enclosure logical id for an expander.
  1317. * Return: 0 for success, non-zero for failure.
  1318. */
  1319. static int
  1320. _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
  1321. {
  1322. struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
  1323. struct _sas_device *sas_device;
  1324. unsigned long flags;
  1325. int rc;
  1326. spin_lock_irqsave(&ioc->sas_device_lock, flags);
  1327. sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
  1328. if (sas_device) {
  1329. *identifier = sas_device->enclosure_logical_id;
  1330. rc = 0;
  1331. sas_device_put(sas_device);
  1332. } else {
  1333. *identifier = 0;
  1334. rc = -ENXIO;
  1335. }
  1336. spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
  1337. return rc;
  1338. }
  1339. /**
  1340. * _transport_get_bay_identifier -
  1341. * @rphy: The sas phy object
  1342. *
  1343. * Return: the slot id for a device that resides inside an enclosure.
  1344. */
  1345. static int
  1346. _transport_get_bay_identifier(struct sas_rphy *rphy)
  1347. {
  1348. struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
  1349. struct _sas_device *sas_device;
  1350. unsigned long flags;
  1351. int rc;
  1352. spin_lock_irqsave(&ioc->sas_device_lock, flags);
  1353. sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
  1354. if (sas_device) {
  1355. rc = sas_device->slot;
  1356. sas_device_put(sas_device);
  1357. } else {
  1358. rc = -ENXIO;
  1359. }
  1360. spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
  1361. return rc;
  1362. }
  1363. /* phy control request structure */
  1364. struct phy_control_request {
  1365. u8 smp_frame_type; /* 0x40 */
  1366. u8 function; /* 0x91 */
  1367. u8 allocated_response_length;
  1368. u8 request_length; /* 0x09 */
  1369. u16 expander_change_count;
  1370. u8 reserved_1[3];
  1371. u8 phy_identifier;
  1372. u8 phy_operation;
  1373. u8 reserved_2[13];
  1374. u64 attached_device_name;
  1375. u8 programmed_min_physical_link_rate;
  1376. u8 programmed_max_physical_link_rate;
  1377. u8 reserved_3[6];
  1378. };
  1379. /* phy control reply structure */
  1380. struct phy_control_reply {
  1381. u8 smp_frame_type; /* 0x41 */
  1382. u8 function; /* 0x11 */
  1383. u8 function_result;
  1384. u8 response_length;
  1385. };
  1386. #define SMP_PHY_CONTROL_LINK_RESET (0x01)
  1387. #define SMP_PHY_CONTROL_HARD_RESET (0x02)
  1388. #define SMP_PHY_CONTROL_DISABLE (0x03)
  1389. /**
  1390. * _transport_expander_phy_control - expander phy control
  1391. * @ioc: per adapter object
  1392. * @phy: The sas phy object
  1393. * @phy_operation: ?
  1394. *
  1395. * Return: 0 for success, non-zero for failure.
  1396. *
  1397. */
  1398. static int
  1399. _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
  1400. struct sas_phy *phy, u8 phy_operation)
  1401. {
  1402. Mpi2SmpPassthroughRequest_t *mpi_request;
  1403. Mpi2SmpPassthroughReply_t *mpi_reply;
  1404. struct phy_control_request *phy_control_request;
  1405. struct phy_control_reply *phy_control_reply;
  1406. int rc;
  1407. u16 smid;
  1408. void *psge;
  1409. u8 issue_reset = 0;
  1410. void *data_out = NULL;
  1411. dma_addr_t data_out_dma;
  1412. u32 sz;
  1413. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  1414. ioc_info(ioc, "%s: host reset in progress!\n", __func__);
  1415. return -EFAULT;
  1416. }
  1417. mutex_lock(&ioc->transport_cmds.mutex);
  1418. if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
  1419. ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
  1420. rc = -EAGAIN;
  1421. goto out;
  1422. }
  1423. ioc->transport_cmds.status = MPT3_CMD_PENDING;
  1424. rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
  1425. if (rc)
  1426. goto out;
  1427. smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
  1428. if (!smid) {
  1429. ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
  1430. rc = -EAGAIN;
  1431. goto out;
  1432. }
  1433. mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
  1434. ioc->transport_cmds.smid = smid;
  1435. sz = sizeof(struct phy_control_request) +
  1436. sizeof(struct phy_control_reply);
  1437. data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma,
  1438. GFP_KERNEL);
  1439. if (!data_out) {
  1440. pr_err("failure at %s:%d/%s()!\n", __FILE__,
  1441. __LINE__, __func__);
  1442. rc = -ENOMEM;
  1443. mpt3sas_base_free_smid(ioc, smid);
  1444. goto out;
  1445. }
  1446. rc = -EINVAL;
  1447. memset(data_out, 0, sz);
  1448. phy_control_request = data_out;
  1449. phy_control_request->smp_frame_type = 0x40;
  1450. phy_control_request->function = 0x91;
  1451. phy_control_request->request_length = 9;
  1452. phy_control_request->allocated_response_length = 0;
  1453. phy_control_request->phy_identifier = phy->number;
  1454. phy_control_request->phy_operation = phy_operation;
  1455. phy_control_request->programmed_min_physical_link_rate =
  1456. phy->minimum_linkrate << 4;
  1457. phy_control_request->programmed_max_physical_link_rate =
  1458. phy->maximum_linkrate << 4;
  1459. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  1460. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  1461. mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
  1462. mpi_request->VF_ID = 0; /* TODO */
  1463. mpi_request->VP_ID = 0;
  1464. mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
  1465. mpi_request->RequestDataLength =
  1466. cpu_to_le16(sizeof(struct phy_error_log_request));
  1467. psge = &mpi_request->SGL;
  1468. ioc->build_sg(ioc, psge, data_out_dma,
  1469. sizeof(struct phy_control_request),
  1470. data_out_dma + sizeof(struct phy_control_request),
  1471. sizeof(struct phy_control_reply));
  1472. dtransportprintk(ioc,
  1473. ioc_info(ioc, "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
  1474. (u64)phy->identify.sas_address,
  1475. phy->number, phy_operation));
  1476. init_completion(&ioc->transport_cmds.done);
  1477. ioc->put_smid_default(ioc, smid);
  1478. wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
  1479. if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
  1480. ioc_err(ioc, "%s: timeout\n", __func__);
  1481. _debug_dump_mf(mpi_request,
  1482. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  1483. if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
  1484. issue_reset = 1;
  1485. goto issue_host_reset;
  1486. }
  1487. dtransportprintk(ioc, ioc_info(ioc, "phy_control - complete\n"));
  1488. if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
  1489. mpi_reply = ioc->transport_cmds.reply;
  1490. dtransportprintk(ioc,
  1491. ioc_info(ioc, "phy_control - reply data transfer size(%d)\n",
  1492. le16_to_cpu(mpi_reply->ResponseDataLength)));
  1493. if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
  1494. sizeof(struct phy_control_reply))
  1495. goto out;
  1496. phy_control_reply = data_out +
  1497. sizeof(struct phy_control_request);
  1498. dtransportprintk(ioc,
  1499. ioc_info(ioc, "phy_control - function_result(%d)\n",
  1500. phy_control_reply->function_result));
  1501. rc = 0;
  1502. } else
  1503. dtransportprintk(ioc,
  1504. ioc_info(ioc, "phy_control - no reply\n"));
  1505. issue_host_reset:
  1506. if (issue_reset)
  1507. mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
  1508. out:
  1509. ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
  1510. if (data_out)
  1511. dma_free_coherent(&ioc->pdev->dev, sz, data_out,
  1512. data_out_dma);
  1513. mutex_unlock(&ioc->transport_cmds.mutex);
  1514. return rc;
  1515. }
  1516. /**
  1517. * _transport_phy_reset -
  1518. * @phy: The sas phy object
  1519. * @hard_reset:
  1520. *
  1521. * Return: 0 for success, non-zero for failure.
  1522. */
  1523. static int
  1524. _transport_phy_reset(struct sas_phy *phy, int hard_reset)
  1525. {
  1526. struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
  1527. Mpi2SasIoUnitControlReply_t mpi_reply;
  1528. Mpi2SasIoUnitControlRequest_t mpi_request;
  1529. struct hba_port *port = phy->hostdata;
  1530. int port_id = port->port_id;
  1531. unsigned long flags;
  1532. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  1533. if (_transport_sas_node_find_by_sas_address(ioc,
  1534. phy->identify.sas_address,
  1535. mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
  1536. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1537. return -EINVAL;
  1538. }
  1539. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1540. /* handle expander phys */
  1541. if (phy->identify.sas_address != ioc->sas_hba.sas_address)
  1542. return _transport_expander_phy_control(ioc, phy,
  1543. (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
  1544. SMP_PHY_CONTROL_LINK_RESET);
  1545. /* handle hba phys */
  1546. memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
  1547. mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
  1548. mpi_request.Operation = hard_reset ?
  1549. MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
  1550. mpi_request.PhyNum = phy->number;
  1551. if ((mpt3sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
  1552. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1553. __FILE__, __LINE__, __func__);
  1554. return -ENXIO;
  1555. }
  1556. if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
  1557. ioc_info(ioc, "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
  1558. phy->number, le16_to_cpu(mpi_reply.IOCStatus),
  1559. le32_to_cpu(mpi_reply.IOCLogInfo));
  1560. return 0;
  1561. }
  1562. /**
  1563. * _transport_phy_enable - enable/disable phys
  1564. * @phy: The sas phy object
  1565. * @enable: enable phy when true
  1566. *
  1567. * Only support sas_host direct attached phys.
  1568. * Return: 0 for success, non-zero for failure.
  1569. */
  1570. static int
  1571. _transport_phy_enable(struct sas_phy *phy, int enable)
  1572. {
  1573. struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
  1574. Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
  1575. Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
  1576. Mpi2ConfigReply_t mpi_reply;
  1577. u16 ioc_status;
  1578. u16 sz;
  1579. int rc = 0;
  1580. unsigned long flags;
  1581. int i, discovery_active;
  1582. struct hba_port *port = phy->hostdata;
  1583. int port_id = port->port_id;
  1584. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  1585. if (_transport_sas_node_find_by_sas_address(ioc,
  1586. phy->identify.sas_address,
  1587. mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
  1588. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1589. return -EINVAL;
  1590. }
  1591. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1592. /* handle expander phys */
  1593. if (phy->identify.sas_address != ioc->sas_hba.sas_address)
  1594. return _transport_expander_phy_control(ioc, phy,
  1595. (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
  1596. SMP_PHY_CONTROL_DISABLE);
  1597. /* handle hba phys */
  1598. /* read sas_iounit page 0 */
  1599. sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
  1600. sizeof(Mpi2SasIOUnit0PhyData_t));
  1601. sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
  1602. if (!sas_iounit_pg0) {
  1603. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1604. __FILE__, __LINE__, __func__);
  1605. rc = -ENOMEM;
  1606. goto out;
  1607. }
  1608. if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
  1609. sas_iounit_pg0, sz))) {
  1610. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1611. __FILE__, __LINE__, __func__);
  1612. rc = -ENXIO;
  1613. goto out;
  1614. }
  1615. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1616. MPI2_IOCSTATUS_MASK;
  1617. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1618. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1619. __FILE__, __LINE__, __func__);
  1620. rc = -EIO;
  1621. goto out;
  1622. }
  1623. /* unable to enable/disable phys when when discovery is active */
  1624. for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
  1625. if (sas_iounit_pg0->PhyData[i].PortFlags &
  1626. MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
  1627. ioc_err(ioc, "discovery is active on port = %d, phy = %d: unable to enable/disable phys, try again later!\n",
  1628. sas_iounit_pg0->PhyData[i].Port, i);
  1629. discovery_active = 1;
  1630. }
  1631. }
  1632. if (discovery_active) {
  1633. rc = -EAGAIN;
  1634. goto out;
  1635. }
  1636. /* read sas_iounit page 1 */
  1637. sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
  1638. sizeof(Mpi2SasIOUnit1PhyData_t));
  1639. sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
  1640. if (!sas_iounit_pg1) {
  1641. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1642. __FILE__, __LINE__, __func__);
  1643. rc = -ENOMEM;
  1644. goto out;
  1645. }
  1646. if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
  1647. sas_iounit_pg1, sz))) {
  1648. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1649. __FILE__, __LINE__, __func__);
  1650. rc = -ENXIO;
  1651. goto out;
  1652. }
  1653. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1654. MPI2_IOCSTATUS_MASK;
  1655. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1656. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1657. __FILE__, __LINE__, __func__);
  1658. rc = -EIO;
  1659. goto out;
  1660. }
  1661. /* copy Port/PortFlags/PhyFlags from page 0 */
  1662. for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
  1663. sas_iounit_pg1->PhyData[i].Port =
  1664. sas_iounit_pg0->PhyData[i].Port;
  1665. sas_iounit_pg1->PhyData[i].PortFlags =
  1666. (sas_iounit_pg0->PhyData[i].PortFlags &
  1667. MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
  1668. sas_iounit_pg1->PhyData[i].PhyFlags =
  1669. (sas_iounit_pg0->PhyData[i].PhyFlags &
  1670. (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
  1671. MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
  1672. }
  1673. if (enable)
  1674. sas_iounit_pg1->PhyData[phy->number].PhyFlags
  1675. &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
  1676. else
  1677. sas_iounit_pg1->PhyData[phy->number].PhyFlags
  1678. |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
  1679. mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
  1680. /* link reset */
  1681. if (enable)
  1682. _transport_phy_reset(phy, 0);
  1683. out:
  1684. kfree(sas_iounit_pg1);
  1685. kfree(sas_iounit_pg0);
  1686. return rc;
  1687. }
  1688. /**
  1689. * _transport_phy_speed - set phy min/max link rates
  1690. * @phy: The sas phy object
  1691. * @rates: rates defined in sas_phy_linkrates
  1692. *
  1693. * Only support sas_host direct attached phys.
  1694. *
  1695. * Return: 0 for success, non-zero for failure.
  1696. */
  1697. static int
  1698. _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
  1699. {
  1700. struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
  1701. Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
  1702. Mpi2SasPhyPage0_t phy_pg0;
  1703. Mpi2ConfigReply_t mpi_reply;
  1704. u16 ioc_status;
  1705. u16 sz;
  1706. int i;
  1707. int rc = 0;
  1708. unsigned long flags;
  1709. struct hba_port *port = phy->hostdata;
  1710. int port_id = port->port_id;
  1711. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  1712. if (_transport_sas_node_find_by_sas_address(ioc,
  1713. phy->identify.sas_address,
  1714. mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
  1715. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1716. return -EINVAL;
  1717. }
  1718. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  1719. if (!rates->minimum_linkrate)
  1720. rates->minimum_linkrate = phy->minimum_linkrate;
  1721. else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
  1722. rates->minimum_linkrate = phy->minimum_linkrate_hw;
  1723. if (!rates->maximum_linkrate)
  1724. rates->maximum_linkrate = phy->maximum_linkrate;
  1725. else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
  1726. rates->maximum_linkrate = phy->maximum_linkrate_hw;
  1727. /* handle expander phys */
  1728. if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
  1729. phy->minimum_linkrate = rates->minimum_linkrate;
  1730. phy->maximum_linkrate = rates->maximum_linkrate;
  1731. return _transport_expander_phy_control(ioc, phy,
  1732. SMP_PHY_CONTROL_LINK_RESET);
  1733. }
  1734. /* handle hba phys */
  1735. /* sas_iounit page 1 */
  1736. sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
  1737. sizeof(Mpi2SasIOUnit1PhyData_t));
  1738. sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
  1739. if (!sas_iounit_pg1) {
  1740. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1741. __FILE__, __LINE__, __func__);
  1742. rc = -ENOMEM;
  1743. goto out;
  1744. }
  1745. if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
  1746. sas_iounit_pg1, sz))) {
  1747. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1748. __FILE__, __LINE__, __func__);
  1749. rc = -ENXIO;
  1750. goto out;
  1751. }
  1752. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1753. MPI2_IOCSTATUS_MASK;
  1754. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1755. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1756. __FILE__, __LINE__, __func__);
  1757. rc = -EIO;
  1758. goto out;
  1759. }
  1760. for (i = 0; i < ioc->sas_hba.num_phys; i++) {
  1761. if (phy->number != i) {
  1762. sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
  1763. (ioc->sas_hba.phy[i].phy->minimum_linkrate +
  1764. (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
  1765. } else {
  1766. sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
  1767. (rates->minimum_linkrate +
  1768. (rates->maximum_linkrate << 4));
  1769. }
  1770. }
  1771. if (mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
  1772. sz)) {
  1773. ioc_err(ioc, "failure at %s:%d/%s()!\n",
  1774. __FILE__, __LINE__, __func__);
  1775. rc = -ENXIO;
  1776. goto out;
  1777. }
  1778. /* link reset */
  1779. _transport_phy_reset(phy, 0);
  1780. /* read phy page 0, then update the rates in the sas transport phy */
  1781. if (!mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
  1782. phy->number)) {
  1783. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  1784. phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  1785. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  1786. phy_pg0.ProgrammedLinkRate >> 4);
  1787. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  1788. phy_pg0.NegotiatedLinkRate &
  1789. MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  1790. }
  1791. out:
  1792. kfree(sas_iounit_pg1);
  1793. return rc;
  1794. }
  1795. static int
  1796. _transport_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
  1797. dma_addr_t *dma_addr, size_t *dma_len, void **p)
  1798. {
  1799. /* Check if the request is split across multiple segments */
  1800. if (buf->sg_cnt > 1) {
  1801. *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr,
  1802. GFP_KERNEL);
  1803. if (!*p)
  1804. return -ENOMEM;
  1805. *dma_len = buf->payload_len;
  1806. } else {
  1807. if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL))
  1808. return -ENOMEM;
  1809. *dma_addr = sg_dma_address(buf->sg_list);
  1810. *dma_len = sg_dma_len(buf->sg_list);
  1811. *p = NULL;
  1812. }
  1813. return 0;
  1814. }
  1815. static void
  1816. _transport_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
  1817. dma_addr_t dma_addr, void *p)
  1818. {
  1819. if (p)
  1820. dma_free_coherent(dev, buf->payload_len, p, dma_addr);
  1821. else
  1822. dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL);
  1823. }
  1824. /**
  1825. * _transport_smp_handler - transport portal for smp passthru
  1826. * @job: ?
  1827. * @shost: shost object
  1828. * @rphy: sas transport rphy object
  1829. *
  1830. * This used primarily for smp_utils.
  1831. * Example:
  1832. * smp_rep_general /sys/class/bsg/expander-5:0
  1833. */
  1834. static void
  1835. _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
  1836. struct sas_rphy *rphy)
  1837. {
  1838. struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
  1839. Mpi2SmpPassthroughRequest_t *mpi_request;
  1840. Mpi2SmpPassthroughReply_t *mpi_reply;
  1841. int rc;
  1842. u16 smid;
  1843. void *psge;
  1844. dma_addr_t dma_addr_in;
  1845. dma_addr_t dma_addr_out;
  1846. void *addr_in = NULL;
  1847. void *addr_out = NULL;
  1848. size_t dma_len_in;
  1849. size_t dma_len_out;
  1850. unsigned int reslen = 0;
  1851. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  1852. ioc_info(ioc, "%s: host reset in progress!\n", __func__);
  1853. rc = -EFAULT;
  1854. goto job_done;
  1855. }
  1856. rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
  1857. if (rc)
  1858. goto job_done;
  1859. if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
  1860. ioc_err(ioc, "%s: transport_cmds in use\n",
  1861. __func__);
  1862. rc = -EAGAIN;
  1863. goto out;
  1864. }
  1865. ioc->transport_cmds.status = MPT3_CMD_PENDING;
  1866. rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->request_payload,
  1867. &dma_addr_out, &dma_len_out, &addr_out);
  1868. if (rc)
  1869. goto out;
  1870. if (addr_out) {
  1871. sg_copy_to_buffer(job->request_payload.sg_list,
  1872. job->request_payload.sg_cnt, addr_out,
  1873. job->request_payload.payload_len);
  1874. }
  1875. rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
  1876. &dma_addr_in, &dma_len_in, &addr_in);
  1877. if (rc)
  1878. goto unmap_out;
  1879. rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
  1880. if (rc)
  1881. goto unmap_in;
  1882. smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
  1883. if (!smid) {
  1884. ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
  1885. rc = -EAGAIN;
  1886. goto unmap_in;
  1887. }
  1888. rc = 0;
  1889. mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
  1890. ioc->transport_cmds.smid = smid;
  1891. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  1892. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  1893. mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy);
  1894. mpi_request->SASAddress = (rphy) ?
  1895. cpu_to_le64(rphy->identify.sas_address) :
  1896. cpu_to_le64(ioc->sas_hba.sas_address);
  1897. mpi_request->RequestDataLength = cpu_to_le16(dma_len_out - 4);
  1898. psge = &mpi_request->SGL;
  1899. ioc->build_sg(ioc, psge, dma_addr_out, dma_len_out - 4, dma_addr_in,
  1900. dma_len_in - 4);
  1901. dtransportprintk(ioc,
  1902. ioc_info(ioc, "%s: sending smp request\n", __func__));
  1903. init_completion(&ioc->transport_cmds.done);
  1904. ioc->put_smid_default(ioc, smid);
  1905. wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
  1906. if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
  1907. ioc_err(ioc, "%s: timeout\n", __func__);
  1908. _debug_dump_mf(mpi_request,
  1909. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  1910. if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) {
  1911. mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
  1912. rc = -ETIMEDOUT;
  1913. goto unmap_in;
  1914. }
  1915. }
  1916. dtransportprintk(ioc, ioc_info(ioc, "%s - complete\n", __func__));
  1917. if (!(ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID)) {
  1918. dtransportprintk(ioc,
  1919. ioc_info(ioc, "%s: no reply\n", __func__));
  1920. rc = -ENXIO;
  1921. goto unmap_in;
  1922. }
  1923. mpi_reply = ioc->transport_cmds.reply;
  1924. dtransportprintk(ioc,
  1925. ioc_info(ioc, "%s: reply data transfer size(%d)\n",
  1926. __func__,
  1927. le16_to_cpu(mpi_reply->ResponseDataLength)));
  1928. memcpy(job->reply, mpi_reply, sizeof(*mpi_reply));
  1929. job->reply_len = sizeof(*mpi_reply);
  1930. reslen = le16_to_cpu(mpi_reply->ResponseDataLength);
  1931. if (addr_in) {
  1932. sg_copy_to_buffer(job->reply_payload.sg_list,
  1933. job->reply_payload.sg_cnt, addr_in,
  1934. job->reply_payload.payload_len);
  1935. }
  1936. rc = 0;
  1937. unmap_in:
  1938. _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
  1939. dma_addr_in, addr_in);
  1940. unmap_out:
  1941. _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->request_payload,
  1942. dma_addr_out, addr_out);
  1943. out:
  1944. ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
  1945. mutex_unlock(&ioc->transport_cmds.mutex);
  1946. job_done:
  1947. bsg_job_done(job, rc, reslen);
  1948. }
  1949. struct sas_function_template mpt3sas_transport_functions = {
  1950. .get_linkerrors = _transport_get_linkerrors,
  1951. .get_enclosure_identifier = _transport_get_enclosure_identifier,
  1952. .get_bay_identifier = _transport_get_bay_identifier,
  1953. .phy_reset = _transport_phy_reset,
  1954. .phy_enable = _transport_phy_enable,
  1955. .set_phy_speed = _transport_phy_speed,
  1956. .smp_handler = _transport_smp_handler,
  1957. };
  1958. struct scsi_transport_template *mpt3sas_transport_template;