mpt2sas_transport.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  1. /*
  2. * SAS Transport Layer for MPT (Message Passing Technology) based controllers
  3. *
  4. * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
  5. * Copyright (C) 2007-2009 LSI Corporation
  6. * (mailto:DL-MPTFusionLinux@lsi.com)
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * NO WARRANTY
  19. * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  20. * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  21. * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  22. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  23. * solely responsible for determining the appropriateness of using and
  24. * distributing the Program and assumes all risks associated with its
  25. * exercise of rights under this Agreement, including but not limited to
  26. * the risks and costs of program errors, damage to or loss of data,
  27. * programs or equipment, and unavailability or interruption of operations.
  28. * DISCLAIMER OF LIABILITY
  29. * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  30. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31. * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  32. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  33. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  34. * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  35. * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  36. * You should have received a copy of the GNU General Public License
  37. * along with this program; if not, write to the Free Software
  38. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  39. * USA.
  40. */
  41. #include <linux/module.h>
  42. #include <linux/kernel.h>
  43. #include <linux/init.h>
  44. #include <linux/errno.h>
  45. #include <linux/sched.h>
  46. #include <linux/workqueue.h>
  47. #include <linux/delay.h>
  48. #include <linux/pci.h>
  49. #include <scsi/scsi.h>
  50. #include <scsi/scsi_cmnd.h>
  51. #include <scsi/scsi_device.h>
  52. #include <scsi/scsi_host.h>
  53. #include <scsi/scsi_transport_sas.h>
  54. #include <scsi/scsi_dbg.h>
  55. #include "mpt2sas_base.h"
  56. /**
  57. * _transport_sas_node_find_by_sas_address - sas node search
  58. * @ioc: per adapter object
  59. * @sas_address: sas address of expander or sas host
  60. * Context: Calling function should acquire ioc->sas_node_lock.
  61. *
  62. * Search for either hba phys or expander device based on handle, then returns
  63. * the sas_node object.
  64. */
  65. static struct _sas_node *
  66. _transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
  67. u64 sas_address)
  68. {
  69. if (ioc->sas_hba.sas_address == sas_address)
  70. return &ioc->sas_hba;
  71. else
  72. return mpt2sas_scsih_expander_find_by_sas_address(ioc,
  73. sas_address);
  74. }
  75. /**
  76. * _transport_convert_phy_link_rate -
  77. * @link_rate: link rate returned from mpt firmware
  78. *
  79. * Convert link_rate from mpi fusion into sas_transport form.
  80. */
  81. static enum sas_linkrate
  82. _transport_convert_phy_link_rate(u8 link_rate)
  83. {
  84. enum sas_linkrate rc;
  85. switch (link_rate) {
  86. case MPI2_SAS_NEG_LINK_RATE_1_5:
  87. rc = SAS_LINK_RATE_1_5_GBPS;
  88. break;
  89. case MPI2_SAS_NEG_LINK_RATE_3_0:
  90. rc = SAS_LINK_RATE_3_0_GBPS;
  91. break;
  92. case MPI2_SAS_NEG_LINK_RATE_6_0:
  93. rc = SAS_LINK_RATE_6_0_GBPS;
  94. break;
  95. case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
  96. rc = SAS_PHY_DISABLED;
  97. break;
  98. case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
  99. rc = SAS_LINK_RATE_FAILED;
  100. break;
  101. case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
  102. rc = SAS_SATA_PORT_SELECTOR;
  103. break;
  104. case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
  105. rc = SAS_PHY_RESET_IN_PROGRESS;
  106. break;
  107. default:
  108. case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
  109. case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
  110. rc = SAS_LINK_RATE_UNKNOWN;
  111. break;
  112. }
  113. return rc;
  114. }
  115. /**
  116. * _transport_set_identify - set identify for phys and end devices
  117. * @ioc: per adapter object
  118. * @handle: device handle
  119. * @identify: sas identify info
  120. *
  121. * Populates sas identify info.
  122. *
  123. * Returns 0 for success, non-zero for failure.
  124. */
  125. static int
  126. _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
  127. struct sas_identify *identify)
  128. {
  129. Mpi2SasDevicePage0_t sas_device_pg0;
  130. Mpi2ConfigReply_t mpi_reply;
  131. u32 device_info;
  132. u32 ioc_status;
  133. if (ioc->shost_recovery) {
  134. printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
  135. __func__, ioc->name);
  136. return -EFAULT;
  137. }
  138. if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
  139. MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
  140. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  141. ioc->name, __FILE__, __LINE__, __func__);
  142. return -ENXIO;
  143. }
  144. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  145. MPI2_IOCSTATUS_MASK;
  146. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  147. printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
  148. "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
  149. __FILE__, __LINE__, __func__);
  150. return -EIO;
  151. }
  152. memset(identify, 0, sizeof(identify));
  153. device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
  154. /* sas_address */
  155. identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
  156. /* device_type */
  157. switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
  158. case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
  159. identify->device_type = SAS_PHY_UNUSED;
  160. break;
  161. case MPI2_SAS_DEVICE_INFO_END_DEVICE:
  162. identify->device_type = SAS_END_DEVICE;
  163. break;
  164. case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
  165. identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
  166. break;
  167. case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
  168. identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
  169. break;
  170. }
  171. /* initiator_port_protocols */
  172. if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
  173. identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
  174. if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
  175. identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
  176. if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
  177. identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
  178. if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
  179. identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
  180. /* target_port_protocols */
  181. if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
  182. identify->target_port_protocols |= SAS_PROTOCOL_SSP;
  183. if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
  184. identify->target_port_protocols |= SAS_PROTOCOL_STP;
  185. if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
  186. identify->target_port_protocols |= SAS_PROTOCOL_SMP;
  187. if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
  188. identify->target_port_protocols |= SAS_PROTOCOL_SATA;
  189. return 0;
  190. }
  191. /**
  192. * mpt2sas_transport_done - internal transport layer callback handler.
  193. * @ioc: per adapter object
  194. * @smid: system request message index
  195. * @msix_index: MSIX table index supplied by the OS
  196. * @reply: reply message frame(lower 32bit addr)
  197. *
  198. * Callback handler when sending internal generated transport cmds.
  199. * The callback index passed is `ioc->transport_cb_idx`
  200. *
  201. * Return 1 meaning mf should be freed from _base_interrupt
  202. * 0 means the mf is freed from this function.
  203. */
  204. u8
  205. mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
  206. u32 reply)
  207. {
  208. MPI2DefaultReply_t *mpi_reply;
  209. mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
  210. if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
  211. return 1;
  212. if (ioc->transport_cmds.smid != smid)
  213. return 1;
  214. ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
  215. if (mpi_reply) {
  216. memcpy(ioc->transport_cmds.reply, mpi_reply,
  217. mpi_reply->MsgLength*4);
  218. ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID;
  219. }
  220. ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
  221. complete(&ioc->transport_cmds.done);
  222. return 1;
  223. }
  224. /* report manufacture request structure */
  225. struct rep_manu_request{
  226. u8 smp_frame_type;
  227. u8 function;
  228. u8 reserved;
  229. u8 request_length;
  230. };
  231. /* report manufacture reply structure */
  232. struct rep_manu_reply{
  233. u8 smp_frame_type; /* 0x41 */
  234. u8 function; /* 0x01 */
  235. u8 function_result;
  236. u8 response_length;
  237. u16 expander_change_count;
  238. u8 reserved0[2];
  239. u8 sas_format;
  240. u8 reserved2[3];
  241. u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
  242. u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
  243. u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
  244. u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
  245. u16 component_id;
  246. u8 component_revision_id;
  247. u8 reserved3;
  248. u8 vendor_specific[8];
  249. };
  250. /**
  251. * _transport_expander_report_manufacture - obtain SMP report_manufacture
  252. * @ioc: per adapter object
  253. * @sas_address: expander sas address
  254. * @edev: the sas_expander_device object
  255. *
  256. * Fills in the sas_expander_device object when SMP port is created.
  257. *
  258. * Returns 0 for success, non-zero for failure.
  259. */
  260. static int
  261. _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
  262. u64 sas_address, struct sas_expander_device *edev)
  263. {
  264. Mpi2SmpPassthroughRequest_t *mpi_request;
  265. Mpi2SmpPassthroughReply_t *mpi_reply;
  266. struct rep_manu_reply *manufacture_reply;
  267. struct rep_manu_request *manufacture_request;
  268. int rc;
  269. u16 smid;
  270. u32 ioc_state;
  271. unsigned long timeleft;
  272. void *psge;
  273. u32 sgl_flags;
  274. u8 issue_reset = 0;
  275. void *data_out = NULL;
  276. dma_addr_t data_out_dma;
  277. u32 sz;
  278. u64 *sas_address_le;
  279. u16 wait_state_count;
  280. if (ioc->shost_recovery) {
  281. printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
  282. __func__, ioc->name);
  283. return -EFAULT;
  284. }
  285. mutex_lock(&ioc->transport_cmds.mutex);
  286. if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
  287. printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
  288. ioc->name, __func__);
  289. rc = -EAGAIN;
  290. goto out;
  291. }
  292. ioc->transport_cmds.status = MPT2_CMD_PENDING;
  293. wait_state_count = 0;
  294. ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  295. while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
  296. if (wait_state_count++ == 10) {
  297. printk(MPT2SAS_ERR_FMT
  298. "%s: failed due to ioc not operational\n",
  299. ioc->name, __func__);
  300. rc = -EFAULT;
  301. goto out;
  302. }
  303. ssleep(1);
  304. ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  305. printk(MPT2SAS_INFO_FMT "%s: waiting for "
  306. "operational state(count=%d)\n", ioc->name,
  307. __func__, wait_state_count);
  308. }
  309. if (wait_state_count)
  310. printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
  311. ioc->name, __func__);
  312. smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
  313. if (!smid) {
  314. printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
  315. ioc->name, __func__);
  316. rc = -EAGAIN;
  317. goto out;
  318. }
  319. rc = 0;
  320. mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
  321. ioc->transport_cmds.smid = smid;
  322. sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
  323. data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
  324. if (!data_out) {
  325. printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
  326. __LINE__, __func__);
  327. rc = -ENOMEM;
  328. mpt2sas_base_free_smid(ioc, smid);
  329. goto out;
  330. }
  331. manufacture_request = data_out;
  332. manufacture_request->smp_frame_type = 0x40;
  333. manufacture_request->function = 1;
  334. manufacture_request->reserved = 0;
  335. manufacture_request->request_length = 0;
  336. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  337. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  338. mpi_request->PhysicalPort = 0xFF;
  339. mpi_request->VF_ID = 0; /* TODO */
  340. mpi_request->VP_ID = 0;
  341. sas_address_le = (u64 *)&mpi_request->SASAddress;
  342. *sas_address_le = cpu_to_le64(sas_address);
  343. mpi_request->RequestDataLength =
  344. cpu_to_le16(sizeof(struct rep_manu_request));
  345. psge = &mpi_request->SGL;
  346. /* WRITE sgel first */
  347. sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
  348. MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
  349. sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
  350. ioc->base_add_sg_single(psge, sgl_flags |
  351. sizeof(struct rep_manu_request), data_out_dma);
  352. /* incr sgel */
  353. psge += ioc->sge_size;
  354. /* READ sgel last */
  355. sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
  356. MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
  357. MPI2_SGE_FLAGS_END_OF_LIST);
  358. sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
  359. ioc->base_add_sg_single(psge, sgl_flags |
  360. sizeof(struct rep_manu_reply), data_out_dma +
  361. sizeof(struct rep_manu_request));
  362. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - "
  363. "send to sas_addr(0x%016llx)\n", ioc->name,
  364. (unsigned long long)sas_address));
  365. mpt2sas_base_put_smid_default(ioc, smid);
  366. init_completion(&ioc->transport_cmds.done);
  367. timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
  368. 10*HZ);
  369. if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
  370. printk(MPT2SAS_ERR_FMT "%s: timeout\n",
  371. ioc->name, __func__);
  372. _debug_dump_mf(mpi_request,
  373. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  374. if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
  375. issue_reset = 1;
  376. goto issue_host_reset;
  377. }
  378. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - "
  379. "complete\n", ioc->name));
  380. if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
  381. u8 *tmp;
  382. mpi_reply = ioc->transport_cmds.reply;
  383. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
  384. "report_manufacture - reply data transfer size(%d)\n",
  385. ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
  386. if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
  387. sizeof(struct rep_manu_reply))
  388. goto out;
  389. manufacture_reply = data_out + sizeof(struct rep_manu_request);
  390. strncpy(edev->vendor_id, manufacture_reply->vendor_id,
  391. SAS_EXPANDER_VENDOR_ID_LEN);
  392. strncpy(edev->product_id, manufacture_reply->product_id,
  393. SAS_EXPANDER_PRODUCT_ID_LEN);
  394. strncpy(edev->product_rev, manufacture_reply->product_rev,
  395. SAS_EXPANDER_PRODUCT_REV_LEN);
  396. edev->level = manufacture_reply->sas_format & 1;
  397. if (edev->level) {
  398. strncpy(edev->component_vendor_id,
  399. manufacture_reply->component_vendor_id,
  400. SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
  401. tmp = (u8 *)&manufacture_reply->component_id;
  402. edev->component_id = tmp[0] << 8 | tmp[1];
  403. edev->component_revision_id =
  404. manufacture_reply->component_revision_id;
  405. }
  406. } else
  407. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
  408. "report_manufacture - no reply\n", ioc->name));
  409. issue_host_reset:
  410. if (issue_reset)
  411. mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
  412. FORCE_BIG_HAMMER);
  413. out:
  414. ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
  415. if (data_out)
  416. pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
  417. mutex_unlock(&ioc->transport_cmds.mutex);
  418. return rc;
  419. }
  420. /**
  421. * mpt2sas_transport_port_add - insert port to the list
  422. * @ioc: per adapter object
  423. * @handle: handle of attached device
  424. * @sas_address: sas address of parent expander or sas host
  425. * Context: This function will acquire ioc->sas_node_lock.
  426. *
  427. * Adding new port object to the sas_node->sas_port_list.
  428. *
  429. * Returns mpt2sas_port.
  430. */
  431. struct _sas_port *
  432. mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
  433. u64 sas_address)
  434. {
  435. struct _sas_phy *mpt2sas_phy, *next;
  436. struct _sas_port *mpt2sas_port;
  437. unsigned long flags;
  438. struct _sas_node *sas_node;
  439. struct sas_rphy *rphy;
  440. int i;
  441. struct sas_port *port;
  442. mpt2sas_port = kzalloc(sizeof(struct _sas_port),
  443. GFP_KERNEL);
  444. if (!mpt2sas_port) {
  445. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  446. ioc->name, __FILE__, __LINE__, __func__);
  447. return NULL;
  448. }
  449. INIT_LIST_HEAD(&mpt2sas_port->port_list);
  450. INIT_LIST_HEAD(&mpt2sas_port->phy_list);
  451. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  452. sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
  453. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  454. if (!sas_node) {
  455. printk(MPT2SAS_ERR_FMT "%s: Could not find "
  456. "parent sas_address(0x%016llx)!\n", ioc->name,
  457. __func__, (unsigned long long)sas_address);
  458. goto out_fail;
  459. }
  460. if ((_transport_set_identify(ioc, handle,
  461. &mpt2sas_port->remote_identify))) {
  462. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  463. ioc->name, __FILE__, __LINE__, __func__);
  464. goto out_fail;
  465. }
  466. if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
  467. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  468. ioc->name, __FILE__, __LINE__, __func__);
  469. goto out_fail;
  470. }
  471. for (i = 0; i < sas_node->num_phys; i++) {
  472. if (sas_node->phy[i].remote_identify.sas_address !=
  473. mpt2sas_port->remote_identify.sas_address)
  474. continue;
  475. list_add_tail(&sas_node->phy[i].port_siblings,
  476. &mpt2sas_port->phy_list);
  477. mpt2sas_port->num_phys++;
  478. }
  479. if (!mpt2sas_port->num_phys) {
  480. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  481. ioc->name, __FILE__, __LINE__, __func__);
  482. goto out_fail;
  483. }
  484. port = sas_port_alloc_num(sas_node->parent_dev);
  485. if ((sas_port_add(port))) {
  486. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  487. ioc->name, __FILE__, __LINE__, __func__);
  488. goto out_fail;
  489. }
  490. list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
  491. port_siblings) {
  492. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  493. dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)"
  494. ", sas_addr(0x%016llx), phy(%d)\n", handle,
  495. (unsigned long long)
  496. mpt2sas_port->remote_identify.sas_address,
  497. mpt2sas_phy->phy_id);
  498. sas_port_add_phy(port, mpt2sas_phy->phy);
  499. }
  500. mpt2sas_port->port = port;
  501. if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE)
  502. rphy = sas_end_device_alloc(port);
  503. else
  504. rphy = sas_expander_alloc(port,
  505. mpt2sas_port->remote_identify.device_type);
  506. rphy->identify = mpt2sas_port->remote_identify;
  507. if ((sas_rphy_add(rphy))) {
  508. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  509. ioc->name, __FILE__, __LINE__, __func__);
  510. }
  511. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  512. dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
  513. "sas_addr(0x%016llx)\n", handle,
  514. (unsigned long long)
  515. mpt2sas_port->remote_identify.sas_address);
  516. mpt2sas_port->rphy = rphy;
  517. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  518. list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list);
  519. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  520. /* fill in report manufacture */
  521. if (mpt2sas_port->remote_identify.device_type ==
  522. MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
  523. mpt2sas_port->remote_identify.device_type ==
  524. MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
  525. _transport_expander_report_manufacture(ioc,
  526. mpt2sas_port->remote_identify.sas_address,
  527. rphy_to_expander_device(rphy));
  528. return mpt2sas_port;
  529. out_fail:
  530. list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list,
  531. port_siblings)
  532. list_del(&mpt2sas_phy->port_siblings);
  533. kfree(mpt2sas_port);
  534. return NULL;
  535. }
  536. /**
  537. * mpt2sas_transport_port_remove - remove port from the list
  538. * @ioc: per adapter object
  539. * @sas_address: sas address of attached device
  540. * @sas_address_parent: sas address of parent expander or sas host
  541. * Context: This function will acquire ioc->sas_node_lock.
  542. *
  543. * Removing object and freeing associated memory from the
  544. * ioc->sas_port_list.
  545. *
  546. * Return nothing.
  547. */
  548. void
  549. mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
  550. u64 sas_address_parent)
  551. {
  552. int i;
  553. unsigned long flags;
  554. struct _sas_port *mpt2sas_port, *next;
  555. struct _sas_node *sas_node;
  556. u8 found = 0;
  557. struct _sas_phy *mpt2sas_phy, *next_phy;
  558. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  559. sas_node = _transport_sas_node_find_by_sas_address(ioc,
  560. sas_address_parent);
  561. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  562. if (!sas_node)
  563. return;
  564. list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
  565. port_list) {
  566. if (mpt2sas_port->remote_identify.sas_address != sas_address)
  567. continue;
  568. found = 1;
  569. list_del(&mpt2sas_port->port_list);
  570. goto out;
  571. }
  572. out:
  573. if (!found)
  574. return;
  575. for (i = 0; i < sas_node->num_phys; i++) {
  576. if (sas_node->phy[i].remote_identify.sas_address == sas_address)
  577. memset(&sas_node->phy[i].remote_identify, 0 ,
  578. sizeof(struct sas_identify));
  579. }
  580. list_for_each_entry_safe(mpt2sas_phy, next_phy,
  581. &mpt2sas_port->phy_list, port_siblings) {
  582. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  583. dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
  584. "remove: sas_addr(0x%016llx), phy(%d)\n",
  585. (unsigned long long)
  586. mpt2sas_port->remote_identify.sas_address,
  587. mpt2sas_phy->phy_id);
  588. sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
  589. list_del(&mpt2sas_phy->port_siblings);
  590. }
  591. sas_port_delete(mpt2sas_port->port);
  592. kfree(mpt2sas_port);
  593. }
  594. /**
  595. * mpt2sas_transport_add_host_phy - report sas_host phy to transport
  596. * @ioc: per adapter object
  597. * @mpt2sas_phy: mpt2sas per phy object
  598. * @phy_pg0: sas phy page 0
  599. * @parent_dev: parent device class object
  600. *
  601. * Returns 0 for success, non-zero for failure.
  602. */
  603. int
  604. mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
  605. *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
  606. {
  607. struct sas_phy *phy;
  608. int phy_index = mpt2sas_phy->phy_id;
  609. INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
  610. phy = sas_phy_alloc(parent_dev, phy_index);
  611. if (!phy) {
  612. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  613. ioc->name, __FILE__, __LINE__, __func__);
  614. return -1;
  615. }
  616. if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
  617. &mpt2sas_phy->identify))) {
  618. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  619. ioc->name, __FILE__, __LINE__, __func__);
  620. return -1;
  621. }
  622. phy->identify = mpt2sas_phy->identify;
  623. mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
  624. if (mpt2sas_phy->attached_handle)
  625. _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
  626. &mpt2sas_phy->remote_identify);
  627. phy->identify.phy_identifier = mpt2sas_phy->phy_id;
  628. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  629. phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  630. phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
  631. phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
  632. phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
  633. phy_pg0.HwLinkRate >> 4);
  634. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  635. phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  636. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  637. phy_pg0.ProgrammedLinkRate >> 4);
  638. if ((sas_phy_add(phy))) {
  639. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  640. ioc->name, __FILE__, __LINE__, __func__);
  641. sas_phy_free(phy);
  642. return -1;
  643. }
  644. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  645. dev_printk(KERN_INFO, &phy->dev,
  646. "add: handle(0x%04x), sas_addr(0x%016llx)\n"
  647. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  648. mpt2sas_phy->handle, (unsigned long long)
  649. mpt2sas_phy->identify.sas_address,
  650. mpt2sas_phy->attached_handle,
  651. (unsigned long long)
  652. mpt2sas_phy->remote_identify.sas_address);
  653. mpt2sas_phy->phy = phy;
  654. return 0;
  655. }
  656. /**
  657. * mpt2sas_transport_add_expander_phy - report expander phy to transport
  658. * @ioc: per adapter object
  659. * @mpt2sas_phy: mpt2sas per phy object
  660. * @expander_pg1: expander page 1
  661. * @parent_dev: parent device class object
  662. *
  663. * Returns 0 for success, non-zero for failure.
  664. */
  665. int
  666. mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
  667. *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev)
  668. {
  669. struct sas_phy *phy;
  670. int phy_index = mpt2sas_phy->phy_id;
  671. INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
  672. phy = sas_phy_alloc(parent_dev, phy_index);
  673. if (!phy) {
  674. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  675. ioc->name, __FILE__, __LINE__, __func__);
  676. return -1;
  677. }
  678. if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
  679. &mpt2sas_phy->identify))) {
  680. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  681. ioc->name, __FILE__, __LINE__, __func__);
  682. return -1;
  683. }
  684. phy->identify = mpt2sas_phy->identify;
  685. mpt2sas_phy->attached_handle =
  686. le16_to_cpu(expander_pg1.AttachedDevHandle);
  687. if (mpt2sas_phy->attached_handle)
  688. _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
  689. &mpt2sas_phy->remote_identify);
  690. phy->identify.phy_identifier = mpt2sas_phy->phy_id;
  691. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  692. expander_pg1.NegotiatedLinkRate &
  693. MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  694. phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
  695. expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
  696. phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
  697. expander_pg1.HwLinkRate >> 4);
  698. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  699. expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  700. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  701. expander_pg1.ProgrammedLinkRate >> 4);
  702. if ((sas_phy_add(phy))) {
  703. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  704. ioc->name, __FILE__, __LINE__, __func__);
  705. sas_phy_free(phy);
  706. return -1;
  707. }
  708. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  709. dev_printk(KERN_INFO, &phy->dev,
  710. "add: handle(0x%04x), sas_addr(0x%016llx)\n"
  711. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  712. mpt2sas_phy->handle, (unsigned long long)
  713. mpt2sas_phy->identify.sas_address,
  714. mpt2sas_phy->attached_handle,
  715. (unsigned long long)
  716. mpt2sas_phy->remote_identify.sas_address);
  717. mpt2sas_phy->phy = phy;
  718. return 0;
  719. }
  720. /**
  721. * mpt2sas_transport_update_links - refreshing phy link changes
  722. * @ioc: per adapter object
  723. * @sas_address: sas address of parent expander or sas host
  724. * @handle: attached device handle
  725. * @phy_numberv: phy number
  726. * @link_rate: new link rate
  727. *
  728. * Returns nothing.
  729. */
  730. void
  731. mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
  732. u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
  733. {
  734. unsigned long flags;
  735. struct _sas_node *sas_node;
  736. struct _sas_phy *mpt2sas_phy;
  737. if (ioc->shost_recovery)
  738. return;
  739. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  740. sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
  741. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  742. if (!sas_node)
  743. return;
  744. mpt2sas_phy = &sas_node->phy[phy_number];
  745. mpt2sas_phy->attached_handle = handle;
  746. if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
  747. _transport_set_identify(ioc, handle,
  748. &mpt2sas_phy->remote_identify);
  749. else
  750. memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
  751. sas_identify));
  752. if (mpt2sas_phy->phy)
  753. mpt2sas_phy->phy->negotiated_linkrate =
  754. _transport_convert_phy_link_rate(link_rate);
  755. if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
  756. dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
  757. "refresh: parent sas_addr(0x%016llx),\n"
  758. "\tlink_rate(0x%02x), phy(%d)\n"
  759. "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
  760. (unsigned long long)sas_address,
  761. link_rate, phy_number, handle, (unsigned long long)
  762. mpt2sas_phy->remote_identify.sas_address);
  763. }
  764. static inline void *
  765. phy_to_ioc(struct sas_phy *phy)
  766. {
  767. struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
  768. return shost_priv(shost);
  769. }
  770. static inline void *
  771. rphy_to_ioc(struct sas_rphy *rphy)
  772. {
  773. struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
  774. return shost_priv(shost);
  775. }
  776. static struct _sas_phy *
  777. _transport_find_local_phy(struct MPT2SAS_ADAPTER *ioc, struct sas_phy *phy)
  778. {
  779. int i;
  780. for (i = 0; i < ioc->sas_hba.num_phys; i++)
  781. if (ioc->sas_hba.phy[i].phy == phy)
  782. return(&ioc->sas_hba.phy[i]);
  783. return NULL;
  784. }
  785. /**
  786. * _transport_get_linkerrors -
  787. * @phy: The sas phy object
  788. *
  789. * Only support sas_host direct attached phys.
  790. * Returns 0 for success, non-zero for failure.
  791. *
  792. */
  793. static int
  794. _transport_get_linkerrors(struct sas_phy *phy)
  795. {
  796. struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
  797. struct _sas_phy *mpt2sas_phy;
  798. Mpi2ConfigReply_t mpi_reply;
  799. Mpi2SasPhyPage1_t phy_pg1;
  800. mpt2sas_phy = _transport_find_local_phy(ioc, phy);
  801. if (!mpt2sas_phy) /* this phy not on sas_host */
  802. return -EINVAL;
  803. if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
  804. mpt2sas_phy->phy_id))) {
  805. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  806. ioc->name, __FILE__, __LINE__, __func__);
  807. return -ENXIO;
  808. }
  809. if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
  810. printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
  811. "(0x%04x), loginfo(0x%08x)\n", ioc->name,
  812. mpt2sas_phy->phy_id,
  813. le16_to_cpu(mpi_reply.IOCStatus),
  814. le32_to_cpu(mpi_reply.IOCLogInfo));
  815. phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
  816. phy->running_disparity_error_count =
  817. le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
  818. phy->loss_of_dword_sync_count =
  819. le32_to_cpu(phy_pg1.LossDwordSynchCount);
  820. phy->phy_reset_problem_count =
  821. le32_to_cpu(phy_pg1.PhyResetProblemCount);
  822. return 0;
  823. }
  824. /**
  825. * _transport_get_enclosure_identifier -
  826. * @phy: The sas phy object
  827. *
  828. * Obtain the enclosure logical id for an expander.
  829. * Returns 0 for success, non-zero for failure.
  830. */
  831. static int
  832. _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
  833. {
  834. struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
  835. struct _sas_node *sas_expander;
  836. unsigned long flags;
  837. spin_lock_irqsave(&ioc->sas_node_lock, flags);
  838. sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
  839. rphy->identify.sas_address);
  840. spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
  841. if (!sas_expander)
  842. return -ENXIO;
  843. *identifier = sas_expander->enclosure_logical_id;
  844. return 0;
  845. }
  846. /**
  847. * _transport_get_bay_identifier -
  848. * @phy: The sas phy object
  849. *
  850. * Returns the slot id for a device that resides inside an enclosure.
  851. */
  852. static int
  853. _transport_get_bay_identifier(struct sas_rphy *rphy)
  854. {
  855. struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
  856. struct _sas_device *sas_device;
  857. unsigned long flags;
  858. spin_lock_irqsave(&ioc->sas_device_lock, flags);
  859. sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
  860. rphy->identify.sas_address);
  861. spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
  862. if (!sas_device)
  863. return -ENXIO;
  864. return sas_device->slot;
  865. }
  866. /**
  867. * _transport_phy_reset -
  868. * @phy: The sas phy object
  869. * @hard_reset:
  870. *
  871. * Only support sas_host direct attached phys.
  872. * Returns 0 for success, non-zero for failure.
  873. */
  874. static int
  875. _transport_phy_reset(struct sas_phy *phy, int hard_reset)
  876. {
  877. struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
  878. struct _sas_phy *mpt2sas_phy;
  879. Mpi2SasIoUnitControlReply_t mpi_reply;
  880. Mpi2SasIoUnitControlRequest_t mpi_request;
  881. mpt2sas_phy = _transport_find_local_phy(ioc, phy);
  882. if (!mpt2sas_phy) /* this phy not on sas_host */
  883. return -EINVAL;
  884. memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
  885. mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
  886. mpi_request.Operation = hard_reset ?
  887. MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
  888. mpi_request.PhyNum = mpt2sas_phy->phy_id;
  889. if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
  890. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  891. ioc->name, __FILE__, __LINE__, __func__);
  892. return -ENXIO;
  893. }
  894. if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
  895. printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
  896. "(0x%04x), loginfo(0x%08x)\n", ioc->name,
  897. mpt2sas_phy->phy_id,
  898. le16_to_cpu(mpi_reply.IOCStatus),
  899. le32_to_cpu(mpi_reply.IOCLogInfo));
  900. return 0;
  901. }
  902. /**
  903. * _transport_phy_enable - enable/disable phys
  904. * @phy: The sas phy object
  905. * @enable: enable phy when true
  906. *
  907. * Only support sas_host direct attached phys.
  908. * Returns 0 for success, non-zero for failure.
  909. */
  910. static int
  911. _transport_phy_enable(struct sas_phy *phy, int enable)
  912. {
  913. struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
  914. struct _sas_phy *mpt2sas_phy;
  915. Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
  916. Mpi2ConfigReply_t mpi_reply;
  917. u16 ioc_status;
  918. u16 sz;
  919. int rc = 0;
  920. mpt2sas_phy = _transport_find_local_phy(ioc, phy);
  921. if (!mpt2sas_phy) /* this phy not on sas_host */
  922. return -EINVAL;
  923. /* sas_iounit page 1 */
  924. sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
  925. sizeof(Mpi2SasIOUnit1PhyData_t));
  926. sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
  927. if (!sas_iounit_pg1) {
  928. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  929. ioc->name, __FILE__, __LINE__, __func__);
  930. rc = -ENOMEM;
  931. goto out;
  932. }
  933. if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
  934. sas_iounit_pg1, sz))) {
  935. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  936. ioc->name, __FILE__, __LINE__, __func__);
  937. rc = -ENXIO;
  938. goto out;
  939. }
  940. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  941. MPI2_IOCSTATUS_MASK;
  942. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  943. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  944. ioc->name, __FILE__, __LINE__, __func__);
  945. rc = -EIO;
  946. goto out;
  947. }
  948. if (enable)
  949. sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags
  950. &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
  951. else
  952. sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags
  953. |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
  954. mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
  955. out:
  956. kfree(sas_iounit_pg1);
  957. return rc;
  958. }
  959. /**
  960. * _transport_phy_speed - set phy min/max link rates
  961. * @phy: The sas phy object
  962. * @rates: rates defined in sas_phy_linkrates
  963. *
  964. * Only support sas_host direct attached phys.
  965. * Returns 0 for success, non-zero for failure.
  966. */
  967. static int
  968. _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
  969. {
  970. struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
  971. struct _sas_phy *mpt2sas_phy;
  972. Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
  973. Mpi2SasPhyPage0_t phy_pg0;
  974. Mpi2ConfigReply_t mpi_reply;
  975. u16 ioc_status;
  976. u16 sz;
  977. int i;
  978. int rc = 0;
  979. mpt2sas_phy = _transport_find_local_phy(ioc, phy);
  980. if (!mpt2sas_phy) /* this phy not on sas_host */
  981. return -EINVAL;
  982. if (!rates->minimum_linkrate)
  983. rates->minimum_linkrate = phy->minimum_linkrate;
  984. else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
  985. rates->minimum_linkrate = phy->minimum_linkrate_hw;
  986. if (!rates->maximum_linkrate)
  987. rates->maximum_linkrate = phy->maximum_linkrate;
  988. else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
  989. rates->maximum_linkrate = phy->maximum_linkrate_hw;
  990. /* sas_iounit page 1 */
  991. sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
  992. sizeof(Mpi2SasIOUnit1PhyData_t));
  993. sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
  994. if (!sas_iounit_pg1) {
  995. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  996. ioc->name, __FILE__, __LINE__, __func__);
  997. rc = -ENOMEM;
  998. goto out;
  999. }
  1000. if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
  1001. sas_iounit_pg1, sz))) {
  1002. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  1003. ioc->name, __FILE__, __LINE__, __func__);
  1004. rc = -ENXIO;
  1005. goto out;
  1006. }
  1007. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1008. MPI2_IOCSTATUS_MASK;
  1009. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1010. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  1011. ioc->name, __FILE__, __LINE__, __func__);
  1012. rc = -EIO;
  1013. goto out;
  1014. }
  1015. for (i = 0; i < ioc->sas_hba.num_phys; i++) {
  1016. if (mpt2sas_phy->phy_id != i) {
  1017. sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
  1018. (ioc->sas_hba.phy[i].phy->minimum_linkrate +
  1019. (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
  1020. } else {
  1021. sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
  1022. (rates->minimum_linkrate +
  1023. (rates->maximum_linkrate << 4));
  1024. }
  1025. }
  1026. if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
  1027. sz)) {
  1028. printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
  1029. ioc->name, __FILE__, __LINE__, __func__);
  1030. rc = -ENXIO;
  1031. goto out;
  1032. }
  1033. /* link reset */
  1034. _transport_phy_reset(phy, 0);
  1035. /* read phy page 0, then update the rates in the sas transport phy */
  1036. if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
  1037. mpt2sas_phy->phy_id)) {
  1038. phy->minimum_linkrate = _transport_convert_phy_link_rate(
  1039. phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
  1040. phy->maximum_linkrate = _transport_convert_phy_link_rate(
  1041. phy_pg0.ProgrammedLinkRate >> 4);
  1042. phy->negotiated_linkrate = _transport_convert_phy_link_rate(
  1043. phy_pg0.NegotiatedLinkRate &
  1044. MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
  1045. }
  1046. out:
  1047. kfree(sas_iounit_pg1);
  1048. return rc;
  1049. }
  1050. /**
  1051. * _transport_smp_handler - transport portal for smp passthru
  1052. * @shost: shost object
  1053. * @rphy: sas transport rphy object
  1054. * @req:
  1055. *
  1056. * This used primarily for smp_utils.
  1057. * Example:
  1058. * smp_rep_general /sys/class/bsg/expander-5:0
  1059. */
  1060. static int
  1061. _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
  1062. struct request *req)
  1063. {
  1064. struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
  1065. Mpi2SmpPassthroughRequest_t *mpi_request;
  1066. Mpi2SmpPassthroughReply_t *mpi_reply;
  1067. int rc;
  1068. u16 smid;
  1069. u32 ioc_state;
  1070. unsigned long timeleft;
  1071. void *psge;
  1072. u32 sgl_flags;
  1073. u8 issue_reset = 0;
  1074. dma_addr_t dma_addr_in = 0;
  1075. dma_addr_t dma_addr_out = 0;
  1076. u16 wait_state_count;
  1077. struct request *rsp = req->next_rq;
  1078. if (!rsp) {
  1079. printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
  1080. "missing\n", ioc->name, __func__);
  1081. return -EINVAL;
  1082. }
  1083. /* do we need to support multiple segments? */
  1084. if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
  1085. printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, "
  1086. "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt,
  1087. blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
  1088. return -EINVAL;
  1089. }
  1090. if (ioc->shost_recovery) {
  1091. printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
  1092. __func__, ioc->name);
  1093. return -EFAULT;
  1094. }
  1095. rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
  1096. if (rc)
  1097. return rc;
  1098. if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
  1099. printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
  1100. __func__);
  1101. rc = -EAGAIN;
  1102. goto out;
  1103. }
  1104. ioc->transport_cmds.status = MPT2_CMD_PENDING;
  1105. wait_state_count = 0;
  1106. ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  1107. while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
  1108. if (wait_state_count++ == 10) {
  1109. printk(MPT2SAS_ERR_FMT
  1110. "%s: failed due to ioc not operational\n",
  1111. ioc->name, __func__);
  1112. rc = -EFAULT;
  1113. goto out;
  1114. }
  1115. ssleep(1);
  1116. ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  1117. printk(MPT2SAS_INFO_FMT "%s: waiting for "
  1118. "operational state(count=%d)\n", ioc->name,
  1119. __func__, wait_state_count);
  1120. }
  1121. if (wait_state_count)
  1122. printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
  1123. ioc->name, __func__);
  1124. smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
  1125. if (!smid) {
  1126. printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
  1127. ioc->name, __func__);
  1128. rc = -EAGAIN;
  1129. goto out;
  1130. }
  1131. rc = 0;
  1132. mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
  1133. ioc->transport_cmds.smid = smid;
  1134. memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
  1135. mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
  1136. mpi_request->PhysicalPort = 0xFF;
  1137. mpi_request->VF_ID = 0; /* TODO */
  1138. mpi_request->VP_ID = 0;
  1139. *((u64 *)&mpi_request->SASAddress) = (rphy) ?
  1140. cpu_to_le64(rphy->identify.sas_address) :
  1141. cpu_to_le64(ioc->sas_hba.sas_address);
  1142. mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
  1143. psge = &mpi_request->SGL;
  1144. /* WRITE sgel first */
  1145. sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
  1146. MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
  1147. sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
  1148. dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
  1149. blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
  1150. if (!dma_addr_out) {
  1151. mpt2sas_base_free_smid(ioc, smid);
  1152. goto unmap;
  1153. }
  1154. ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4),
  1155. dma_addr_out);
  1156. /* incr sgel */
  1157. psge += ioc->sge_size;
  1158. /* READ sgel last */
  1159. sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
  1160. MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
  1161. MPI2_SGE_FLAGS_END_OF_LIST);
  1162. sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
  1163. dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
  1164. blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
  1165. if (!dma_addr_in) {
  1166. mpt2sas_base_free_smid(ioc, smid);
  1167. goto unmap;
  1168. }
  1169. ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4),
  1170. dma_addr_in);
  1171. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
  1172. "sending smp request\n", ioc->name, __func__));
  1173. mpt2sas_base_put_smid_default(ioc, smid);
  1174. init_completion(&ioc->transport_cmds.done);
  1175. timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
  1176. 10*HZ);
  1177. if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
  1178. printk(MPT2SAS_ERR_FMT "%s : timeout\n",
  1179. __func__, ioc->name);
  1180. _debug_dump_mf(mpi_request,
  1181. sizeof(Mpi2SmpPassthroughRequest_t)/4);
  1182. if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
  1183. issue_reset = 1;
  1184. goto issue_host_reset;
  1185. }
  1186. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
  1187. "complete\n", ioc->name, __func__));
  1188. if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
  1189. mpi_reply = ioc->transport_cmds.reply;
  1190. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
  1191. "%s - reply data transfer size(%d)\n",
  1192. ioc->name, __func__,
  1193. le16_to_cpu(mpi_reply->ResponseDataLength)));
  1194. memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
  1195. req->sense_len = sizeof(*mpi_reply);
  1196. req->resid_len = 0;
  1197. rsp->resid_len -= mpi_reply->ResponseDataLength;
  1198. } else {
  1199. dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
  1200. "%s - no reply\n", ioc->name, __func__));
  1201. rc = -ENXIO;
  1202. }
  1203. issue_host_reset:
  1204. if (issue_reset) {
  1205. mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
  1206. FORCE_BIG_HAMMER);
  1207. rc = -ETIMEDOUT;
  1208. }
  1209. unmap:
  1210. if (dma_addr_out)
  1211. pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
  1212. PCI_DMA_BIDIRECTIONAL);
  1213. if (dma_addr_in)
  1214. pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
  1215. PCI_DMA_BIDIRECTIONAL);
  1216. out:
  1217. ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
  1218. mutex_unlock(&ioc->transport_cmds.mutex);
  1219. return rc;
  1220. }
  1221. struct sas_function_template mpt2sas_transport_functions = {
  1222. .get_linkerrors = _transport_get_linkerrors,
  1223. .get_enclosure_identifier = _transport_get_enclosure_identifier,
  1224. .get_bay_identifier = _transport_get_bay_identifier,
  1225. .phy_reset = _transport_phy_reset,
  1226. .phy_enable = _transport_phy_enable,
  1227. .set_phy_speed = _transport_phy_speed,
  1228. .smp_handler = _transport_smp_handler,
  1229. };
  1230. struct scsi_transport_template *mpt2sas_transport_template;