|
|
1.1 root 1: /*
2: * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3: *
4: * PAPR Virtual SCSI, aka ibmvscsi
5: *
6: * Copyright (c) 2010,2011 Benjamin Herrenschmidt, IBM Corporation.
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: *
26: * TODO:
27: *
28: * - Cleanups :-)
29: * - Sort out better how to assign devices to VSCSI instances
30: * - Fix residual counts
31: * - Add indirect descriptors support
32: * - Maybe do autosense (PAPR seems to mandate it, linux doesn't care)
33: */
34: #include "hw.h"
35: #include "scsi.h"
36: #include "scsi-defs.h"
37: #include "net.h" /* Remove that when we can */
38: #include "srp.h"
39: #include "hw/qdev.h"
40: #include "hw/spapr.h"
41: #include "hw/spapr_vio.h"
42: #include "hw/ppc-viosrp.h"
43:
44: #include <libfdt.h>
45:
46: /*#define DEBUG_VSCSI*/
47:
48: #ifdef DEBUG_VSCSI
49: #define dprintf(fmt, ...) \
50: do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
51: #else
52: #define dprintf(fmt, ...) \
53: do { } while (0)
54: #endif
55:
56: /*
57: * Virtual SCSI device
58: */
59:
60: /* Random numbers */
61: #define VSCSI_MAX_SECTORS 4096
62: #define VSCSI_REQ_LIMIT 24
63:
64: #define SCSI_SENSE_BUF_SIZE 96
65: #define SRP_RSP_SENSE_DATA_LEN 18
66:
67: typedef union vscsi_crq {
68: struct viosrp_crq s;
69: uint8_t raw[16];
70: } vscsi_crq;
71:
72: typedef struct vscsi_req {
73: vscsi_crq crq;
74: union viosrp_iu iu;
75:
76: /* SCSI request tracking */
77: SCSIRequest *sreq;
78: uint32_t qtag; /* qemu tag != srp tag */
79: int lun;
80: int active;
81: long data_len;
82: int writing;
83: int senselen;
84: uint8_t sense[SCSI_SENSE_BUF_SIZE];
85:
86: /* RDMA related bits */
87: uint8_t dma_fmt;
88: struct srp_direct_buf ext_desc;
89: struct srp_direct_buf *cur_desc;
90: struct srp_indirect_buf *ind_desc;
91: int local_desc;
92: int total_desc;
93: } vscsi_req;
94:
95:
96: typedef struct {
97: VIOsPAPRDevice vdev;
98: SCSIBus bus;
99: vscsi_req reqs[VSCSI_REQ_LIMIT];
100: } VSCSIState;
101:
102: /* XXX Debug only */
103: static VSCSIState *dbg_vscsi_state;
104:
105:
106: static struct vscsi_req *vscsi_get_req(VSCSIState *s)
107: {
108: vscsi_req *req;
109: int i;
110:
111: for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
112: req = &s->reqs[i];
113: if (!req->active) {
114: memset(req, 0, sizeof(*req));
115: req->qtag = i;
116: req->active = 1;
117: return req;
118: }
119: }
120: return NULL;
121: }
122:
123: static void vscsi_put_req(vscsi_req *req)
124: {
125: if (req->sreq != NULL) {
126: scsi_req_unref(req->sreq);
127: }
128: req->sreq = NULL;
129: req->active = 0;
130: }
131:
1.1.1.2 ! root 132: static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, int *lun)
1.1 root 133: {
1.1.1.2 ! root 134: int channel = 0, id = 0;
! 135:
! 136: retry:
! 137: switch (srp_lun >> 62) {
! 138: case 0:
! 139: if ((srp_lun >> 56) != 0) {
! 140: channel = (srp_lun >> 56) & 0x3f;
! 141: id = (srp_lun >> 48) & 0xff;
! 142: srp_lun <<= 16;
! 143: goto retry;
! 144: }
! 145: *lun = (srp_lun >> 48) & 0xff;
! 146: break;
! 147:
! 148: case 1:
! 149: *lun = (srp_lun >> 48) & 0x3fff;
! 150: break;
! 151: case 2:
! 152: channel = (srp_lun >> 53) & 0x7;
! 153: id = (srp_lun >> 56) & 0x3f;
! 154: *lun = (srp_lun >> 48) & 0x1f;
! 155: break;
! 156: case 3:
! 157: *lun = -1;
! 158: return NULL;
! 159: default:
! 160: abort();
! 161: }
! 162:
! 163: return scsi_device_find(bus, channel, id, *lun);
1.1 root 164: }
165:
166: static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
167: uint64_t length, uint8_t format)
168: {
169: long rc, rc1;
170:
171: /* First copy the SRP */
172: rc = spapr_tce_dma_write(&s->vdev, req->crq.s.IU_data_ptr,
173: &req->iu, length);
174: if (rc) {
175: fprintf(stderr, "vscsi_send_iu: DMA write failure !\n");
176: }
177:
178: req->crq.s.valid = 0x80;
179: req->crq.s.format = format;
180: req->crq.s.reserved = 0x00;
181: req->crq.s.timeout = cpu_to_be16(0x0000);
182: req->crq.s.IU_length = cpu_to_be16(length);
183: req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
184:
185: if (rc == 0) {
186: req->crq.s.status = 0x99; /* Just needs to be non-zero */
187: } else {
188: req->crq.s.status = 0x00;
189: }
190:
191: rc1 = spapr_vio_send_crq(&s->vdev, req->crq.raw);
192: if (rc1) {
193: fprintf(stderr, "vscsi_send_iu: Error sending response\n");
194: return rc1;
195: }
196:
197: return rc;
198: }
199:
200: static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req,
201: uint8_t key, uint8_t asc, uint8_t ascq)
202: {
203: req->senselen = SRP_RSP_SENSE_DATA_LEN;
204:
205: /* Valid bit and 'current errors' */
206: req->sense[0] = (0x1 << 7 | 0x70);
207: /* Sense key */
208: req->sense[2] = key;
209: /* Additional sense length */
210: req->sense[7] = 0xa; /* 10 bytes */
211: /* Additional sense code */
212: req->sense[12] = asc;
213: req->sense[13] = ascq;
214: }
215:
216: static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
217: uint8_t status, int32_t res_in, int32_t res_out)
218: {
219: union viosrp_iu *iu = &req->iu;
220: uint64_t tag = iu->srp.rsp.tag;
221: int total_len = sizeof(iu->srp.rsp);
222:
223: dprintf("VSCSI: Sending resp status: 0x%x, "
224: "res_in: %d, res_out: %d\n", status, res_in, res_out);
225:
226: memset(iu, 0, sizeof(struct srp_rsp));
227: iu->srp.rsp.opcode = SRP_RSP;
228: iu->srp.rsp.req_lim_delta = cpu_to_be32(1);
229: iu->srp.rsp.tag = tag;
230:
231: /* Handle residuals */
232: if (res_in < 0) {
233: iu->srp.rsp.flags |= SRP_RSP_FLAG_DIUNDER;
234: res_in = -res_in;
235: } else if (res_in) {
236: iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER;
237: }
238: if (res_out < 0) {
239: iu->srp.rsp.flags |= SRP_RSP_FLAG_DOUNDER;
240: res_out = -res_out;
241: } else if (res_out) {
242: iu->srp.rsp.flags |= SRP_RSP_FLAG_DOOVER;
243: }
244: iu->srp.rsp.data_in_res_cnt = cpu_to_be32(res_in);
245: iu->srp.rsp.data_out_res_cnt = cpu_to_be32(res_out);
246:
247: /* We don't do response data */
248: /* iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID; */
249: iu->srp.rsp.resp_data_len = cpu_to_be32(0);
250:
251: /* Handle success vs. failure */
252: iu->srp.rsp.status = status;
253: if (status) {
254: iu->srp.rsp.sol_not = (iu->srp.cmd.sol_not & 0x04) >> 2;
255: if (req->senselen) {
256: req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
257: req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen);
258: memcpy(req->iu.srp.rsp.data, req->sense, req->senselen);
259: total_len += req->senselen;
260: }
261: } else {
262: iu->srp.rsp.sol_not = (iu->srp.cmd.sol_not & 0x02) >> 1;
263: }
264:
265: vscsi_send_iu(s, req, total_len, VIOSRP_SRP_FORMAT);
266: return 0;
267: }
268:
269: static inline void vscsi_swap_desc(struct srp_direct_buf *desc)
270: {
271: desc->va = be64_to_cpu(desc->va);
272: desc->len = be32_to_cpu(desc->len);
273: }
274:
275: static int vscsi_srp_direct_data(VSCSIState *s, vscsi_req *req,
276: uint8_t *buf, uint32_t len)
277: {
278: struct srp_direct_buf *md = req->cur_desc;
279: uint32_t llen;
280: int rc = 0;
281:
282: dprintf("VSCSI: direct segment 0x%x bytes, va=0x%llx desc len=0x%x\n",
283: len, (unsigned long long)md->va, md->len);
284:
285: llen = MIN(len, md->len);
286: if (llen) {
287: if (req->writing) { /* writing = to device = reading from memory */
288: rc = spapr_tce_dma_read(&s->vdev, md->va, buf, llen);
289: } else {
290: rc = spapr_tce_dma_write(&s->vdev, md->va, buf, llen);
291: }
292: }
293: md->len -= llen;
294: md->va += llen;
295:
296: if (rc) {
297: return -1;
298: }
299: return llen;
300: }
301:
302: static int vscsi_srp_indirect_data(VSCSIState *s, vscsi_req *req,
303: uint8_t *buf, uint32_t len)
304: {
305: struct srp_direct_buf *td = &req->ind_desc->table_desc;
306: struct srp_direct_buf *md = req->cur_desc;
307: int rc = 0;
308: uint32_t llen, total = 0;
309:
310: dprintf("VSCSI: indirect segment 0x%x bytes, td va=0x%llx len=0x%x\n",
311: len, (unsigned long long)td->va, td->len);
312:
313: /* While we have data ... */
314: while (len) {
315: /* If we have a descriptor but it's empty, go fetch a new one */
316: if (md && md->len == 0) {
317: /* More local available, use one */
318: if (req->local_desc) {
319: md = ++req->cur_desc;
320: --req->local_desc;
321: --req->total_desc;
322: td->va += sizeof(struct srp_direct_buf);
323: } else {
324: md = req->cur_desc = NULL;
325: }
326: }
327: /* No descriptor at hand, fetch one */
328: if (!md) {
329: if (!req->total_desc) {
330: dprintf("VSCSI: Out of descriptors !\n");
331: break;
332: }
333: md = req->cur_desc = &req->ext_desc;
334: dprintf("VSCSI: Reading desc from 0x%llx\n",
335: (unsigned long long)td->va);
336: rc = spapr_tce_dma_read(&s->vdev, td->va, md,
337: sizeof(struct srp_direct_buf));
338: if (rc) {
339: dprintf("VSCSI: tce_dma_read -> %d reading ext_desc\n", rc);
340: break;
341: }
342: vscsi_swap_desc(md);
343: td->va += sizeof(struct srp_direct_buf);
344: --req->total_desc;
345: }
346: dprintf("VSCSI: [desc va=0x%llx,len=0x%x] remaining=0x%x\n",
347: (unsigned long long)md->va, md->len, len);
348:
349: /* Perform transfer */
350: llen = MIN(len, md->len);
351: if (req->writing) { /* writing = to device = reading from memory */
352: rc = spapr_tce_dma_read(&s->vdev, md->va, buf, llen);
353: } else {
354: rc = spapr_tce_dma_write(&s->vdev, md->va, buf, llen);
355: }
356: if (rc) {
357: dprintf("VSCSI: tce_dma_r/w(%d) -> %d\n", req->writing, rc);
358: break;
359: }
360: dprintf("VSCSI: data: %02x %02x %02x %02x...\n",
361: buf[0], buf[1], buf[2], buf[3]);
362:
363: len -= llen;
364: buf += llen;
365: total += llen;
366: md->va += llen;
367: md->len -= llen;
368: }
369: return rc ? -1 : total;
370: }
371:
372: static int vscsi_srp_transfer_data(VSCSIState *s, vscsi_req *req,
373: int writing, uint8_t *buf, uint32_t len)
374: {
375: int err = 0;
376:
377: switch (req->dma_fmt) {
378: case SRP_NO_DATA_DESC:
379: dprintf("VSCSI: no data desc transfer, skipping 0x%x bytes\n", len);
380: break;
381: case SRP_DATA_DESC_DIRECT:
382: err = vscsi_srp_direct_data(s, req, buf, len);
383: break;
384: case SRP_DATA_DESC_INDIRECT:
385: err = vscsi_srp_indirect_data(s, req, buf, len);
386: break;
387: }
388: return err;
389: }
390:
391: /* Bits from linux srp */
392: static int data_out_desc_size(struct srp_cmd *cmd)
393: {
394: int size = 0;
395: uint8_t fmt = cmd->buf_fmt >> 4;
396:
397: switch (fmt) {
398: case SRP_NO_DATA_DESC:
399: break;
400: case SRP_DATA_DESC_DIRECT:
401: size = sizeof(struct srp_direct_buf);
402: break;
403: case SRP_DATA_DESC_INDIRECT:
404: size = sizeof(struct srp_indirect_buf) +
405: sizeof(struct srp_direct_buf)*cmd->data_out_desc_cnt;
406: break;
407: default:
408: break;
409: }
410: return size;
411: }
412:
413: static int vscsi_preprocess_desc(vscsi_req *req)
414: {
415: struct srp_cmd *cmd = &req->iu.srp.cmd;
416: int offset, i;
417:
418: offset = cmd->add_cdb_len & ~3;
419:
420: if (req->writing) {
421: req->dma_fmt = cmd->buf_fmt >> 4;
422: } else {
423: offset += data_out_desc_size(cmd);
424: req->dma_fmt = cmd->buf_fmt & ((1U << 4) - 1);
425: }
426:
427: switch (req->dma_fmt) {
428: case SRP_NO_DATA_DESC:
429: break;
430: case SRP_DATA_DESC_DIRECT:
431: req->cur_desc = (struct srp_direct_buf *)(cmd->add_data + offset);
432: req->total_desc = req->local_desc = 1;
433: vscsi_swap_desc(req->cur_desc);
434: dprintf("VSCSI: using direct RDMA %s, 0x%x bytes MD: 0x%llx\n",
435: req->writing ? "write" : "read",
436: req->cur_desc->len, (unsigned long long)req->cur_desc->va);
437: break;
438: case SRP_DATA_DESC_INDIRECT:
439: req->ind_desc = (struct srp_indirect_buf *)(cmd->add_data + offset);
440: vscsi_swap_desc(&req->ind_desc->table_desc);
441: req->total_desc = req->ind_desc->table_desc.len /
442: sizeof(struct srp_direct_buf);
443: req->local_desc = req->writing ? cmd->data_out_desc_cnt :
444: cmd->data_in_desc_cnt;
445: for (i = 0; i < req->local_desc; i++) {
446: vscsi_swap_desc(&req->ind_desc->desc_list[i]);
447: }
448: req->cur_desc = req->local_desc ? &req->ind_desc->desc_list[0] : NULL;
449: dprintf("VSCSI: using indirect RDMA %s, 0x%x bytes %d descs "
450: "(%d local) VA: 0x%llx\n",
451: req->writing ? "read" : "write",
452: be32_to_cpu(req->ind_desc->len),
453: req->total_desc, req->local_desc,
454: (unsigned long long)req->ind_desc->table_desc.va);
455: break;
456: default:
457: fprintf(stderr,
458: "vscsi_preprocess_desc: Unknown format %x\n", req->dma_fmt);
459: return -1;
460: }
461:
462: return 0;
463: }
464:
465: /* Callback to indicate that the SCSI layer has completed a transfer. */
466: static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
467: {
468: VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
469: vscsi_req *req = sreq->hba_private;
470: uint8_t *buf;
471: int rc = 0;
472:
473: dprintf("VSCSI: SCSI xfer complete tag=0x%x len=0x%x, req=%p\n",
474: sreq->tag, len, req);
475: if (req == NULL) {
476: fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag);
477: return;
478: }
479:
480: if (len) {
481: buf = scsi_req_get_buf(sreq);
482: rc = vscsi_srp_transfer_data(s, req, req->writing, buf, len);
483: }
484: if (rc < 0) {
485: fprintf(stderr, "VSCSI: RDMA error rc=%d!\n", rc);
486: vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
487: scsi_req_abort(req->sreq, CHECK_CONDITION);
488: return;
489: }
490:
491: /* Start next chunk */
492: req->data_len -= rc;
493: scsi_req_continue(sreq);
494: }
495:
496: /* Callback to indicate that the SCSI layer has completed a transfer. */
497: static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
498: {
499: VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
500: vscsi_req *req = sreq->hba_private;
501: int32_t res_in = 0, res_out = 0;
502:
503: dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x status=0x%x, req=%p\n",
504: reason, sreq->tag, status, req);
505: if (req == NULL) {
506: fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag);
507: return;
508: }
509:
1.1.1.2 ! root 510: if (status == CHECK_CONDITION) {
! 511: req->senselen = scsi_req_get_sense(req->sreq, req->sense,
! 512: sizeof(req->sense));
! 513: dprintf("VSCSI: Sense data, %d bytes:\n", len);
! 514: dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
! 515: req->sense[0], req->sense[1], req->sense[2], req->sense[3],
! 516: req->sense[4], req->sense[5], req->sense[6], req->sense[7]);
! 517: dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
! 518: req->sense[8], req->sense[9], req->sense[10], req->sense[11],
! 519: req->sense[12], req->sense[13], req->sense[14], req->sense[15]);
1.1 root 520: }
521:
1.1.1.2 ! root 522: dprintf("VSCSI: Command complete err=%d\n", status);
! 523: if (status == 0) {
! 524: /* We handle overflows, not underflows for normal commands,
! 525: * but hopefully nobody cares
! 526: */
! 527: if (req->writing) {
! 528: res_out = req->data_len;
! 529: } else {
! 530: res_in = req->data_len;
1.1 root 531: }
532: }
1.1.1.2 ! root 533: vscsi_send_rsp(s, req, status, res_in, res_out);
1.1 root 534: vscsi_put_req(req);
535: }
536:
537: static void vscsi_request_cancelled(SCSIRequest *sreq)
538: {
539: vscsi_req *req = sreq->hba_private;
540:
541: vscsi_put_req(req);
542: }
543:
544: static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
545: {
546: union viosrp_iu *iu = &req->iu;
547: struct srp_login_rsp *rsp = &iu->srp.login_rsp;
548: uint64_t tag = iu->srp.rsp.tag;
549:
550: dprintf("VSCSI: Got login, sendin response !\n");
551:
552: /* TODO handle case that requested size is wrong and
553: * buffer format is wrong
554: */
555: memset(iu, 0, sizeof(struct srp_login_rsp));
556: rsp->opcode = SRP_LOGIN_RSP;
557: /* Don't advertise quite as many request as we support to
558: * keep room for management stuff etc...
559: */
560: rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2);
561: rsp->tag = tag;
562: rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu));
563: rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu));
564: /* direct and indirect */
565: rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT);
566:
567: vscsi_send_iu(s, req, sizeof(*rsp), VIOSRP_SRP_FORMAT);
568: }
569:
570: static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)
571: {
572: uint8_t *cdb = req->iu.srp.cmd.cdb;
573: uint8_t resp_data[36];
574: int rc, len, alen;
575:
576: /* We dont do EVPD. Also check that page_code is 0 */
577: if ((cdb[1] & 0x01) || (cdb[1] & 0x01) || cdb[2] != 0) {
578: /* Send INVALID FIELD IN CDB */
579: vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0);
580: vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
581: return;
582: }
583: alen = cdb[3];
584: alen = (alen << 8) | cdb[4];
585: len = MIN(alen, 36);
586:
587: /* Fake up inquiry using PQ=3 */
588: memset(resp_data, 0, 36);
589: resp_data[0] = 0x7f; /* Not capable of supporting a device here */
590: resp_data[2] = 0x06; /* SPS-4 */
591: resp_data[3] = 0x02; /* Resp data format */
592: resp_data[4] = 36 - 5; /* Additional length */
593: resp_data[7] = 0x10; /* Sync transfers */
594: memcpy(&resp_data[16], "QEMU EMPTY ", 16);
595: memcpy(&resp_data[8], "QEMU ", 8);
596:
597: req->writing = 0;
598: vscsi_preprocess_desc(req);
599: rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len);
600: if (rc < 0) {
601: vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
602: vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
603: } else {
604: vscsi_send_rsp(s, req, 0, 36 - rc, 0);
605: }
606: }
607:
608: static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
609: {
610: union srp_iu *srp = &req->iu.srp;
611: SCSIDevice *sdev;
1.1.1.2 ! root 612: int n, lun;
1.1 root 613:
1.1.1.2 ! root 614: sdev = vscsi_device_find(&s->bus, be64_to_cpu(srp->cmd.lun), &lun);
1.1 root 615: if (!sdev) {
1.1.1.2 ! root 616: dprintf("VSCSI: Command for lun %08" PRIx64 " with no drive\n", be64_to_cpu(srp->cmd.lun));
1.1 root 617: if (srp->cmd.cdb[0] == INQUIRY) {
618: vscsi_inquiry_no_target(s, req);
619: } else {
620: vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0x00);
621: vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
622: } return 1;
623: }
624:
625: req->lun = lun;
1.1.1.2 ! root 626: req->sreq = scsi_req_new(sdev, req->qtag, lun, srp->cmd.cdb, req);
! 627: n = scsi_req_enqueue(req->sreq);
1.1 root 628:
629: dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
630: req->qtag, srp->cmd.cdb[0], id, lun, n);
631:
632: if (n) {
633: /* Transfer direction must be set before preprocessing the
634: * descriptors
635: */
636: req->writing = (n < 1);
637:
638: /* Preprocess RDMA descriptors */
639: vscsi_preprocess_desc(req);
640:
641: /* Get transfer direction and initiate transfer */
642: if (n > 0) {
643: req->data_len = n;
644: } else if (n < 0) {
645: req->data_len = -n;
646: }
647: scsi_req_continue(req->sreq);
648: }
649: /* Don't touch req here, it may have been recycled already */
650:
651: return 0;
652: }
653:
654: static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
655: {
656: union viosrp_iu *iu = &req->iu;
657: int fn;
658:
659: fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n",
660: iu->srp.tsk_mgmt.tsk_mgmt_func);
661:
662: switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
663: #if 0 /* We really don't deal with these for now */
664: case SRP_TSK_ABORT_TASK:
665: fn = ABORT_TASK;
666: break;
667: case SRP_TSK_ABORT_TASK_SET:
668: fn = ABORT_TASK_SET;
669: break;
670: case SRP_TSK_CLEAR_TASK_SET:
671: fn = CLEAR_TASK_SET;
672: break;
673: case SRP_TSK_LUN_RESET:
674: fn = LOGICAL_UNIT_RESET;
675: break;
676: case SRP_TSK_CLEAR_ACA:
677: fn = CLEAR_ACA;
678: break;
679: #endif
680: default:
681: fn = 0;
682: }
683: if (fn) {
684: /* XXX Send/Handle target task management */
685: ;
686: } else {
687: vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x20, 0);
688: vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
689: }
690: return !fn;
691: }
692:
693: static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req)
694: {
695: union srp_iu *srp = &req->iu.srp;
696: int done = 1;
697: uint8_t opcode = srp->rsp.opcode;
698:
699: switch (opcode) {
700: case SRP_LOGIN_REQ:
701: vscsi_process_login(s, req);
702: break;
703: case SRP_TSK_MGMT:
704: done = vscsi_process_tsk_mgmt(s, req);
705: break;
706: case SRP_CMD:
707: done = vscsi_queue_cmd(s, req);
708: break;
709: case SRP_LOGIN_RSP:
710: case SRP_I_LOGOUT:
711: case SRP_T_LOGOUT:
712: case SRP_RSP:
713: case SRP_CRED_REQ:
714: case SRP_CRED_RSP:
715: case SRP_AER_REQ:
716: case SRP_AER_RSP:
717: fprintf(stderr, "VSCSI: Unsupported opcode %02x\n", opcode);
718: break;
719: default:
720: fprintf(stderr, "VSCSI: Unknown type %02x\n", opcode);
721: }
722:
723: return done;
724: }
725:
726: static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req)
727: {
728: struct viosrp_adapter_info *sinfo;
729: struct mad_adapter_info_data info;
730: int rc;
731:
732: sinfo = &req->iu.mad.adapter_info;
733:
734: #if 0 /* What for ? */
735: rc = spapr_tce_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer),
736: &info, be16_to_cpu(sinfo->common.length));
737: if (rc) {
738: fprintf(stderr, "vscsi_send_adapter_info: DMA read failure !\n");
739: }
740: #endif
741: memset(&info, 0, sizeof(info));
742: strcpy(info.srp_version, SRP_VERSION);
743: strncpy(info.partition_name, "qemu", sizeof("qemu"));
744: info.partition_number = cpu_to_be32(0);
745: info.mad_version = cpu_to_be32(1);
746: info.os_type = cpu_to_be32(2);
747: info.port_max_txu[0] = cpu_to_be32(VSCSI_MAX_SECTORS << 9);
748:
749: rc = spapr_tce_dma_write(&s->vdev, be64_to_cpu(sinfo->buffer),
750: &info, be16_to_cpu(sinfo->common.length));
751: if (rc) {
752: fprintf(stderr, "vscsi_send_adapter_info: DMA write failure !\n");
753: }
754:
755: sinfo->common.status = rc ? cpu_to_be32(1) : 0;
756:
757: return vscsi_send_iu(s, req, sizeof(*sinfo), VIOSRP_MAD_FORMAT);
758: }
759:
760: static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req)
761: {
762: union mad_iu *mad = &req->iu.mad;
763:
764: switch (be32_to_cpu(mad->empty_iu.common.type)) {
765: case VIOSRP_EMPTY_IU_TYPE:
766: fprintf(stderr, "Unsupported EMPTY MAD IU\n");
767: break;
768: case VIOSRP_ERROR_LOG_TYPE:
769: fprintf(stderr, "Unsupported ERROR LOG MAD IU\n");
770: mad->error_log.common.status = cpu_to_be16(1);
771: vscsi_send_iu(s, req, sizeof(mad->error_log), VIOSRP_MAD_FORMAT);
772: break;
773: case VIOSRP_ADAPTER_INFO_TYPE:
774: vscsi_send_adapter_info(s, req);
775: break;
776: case VIOSRP_HOST_CONFIG_TYPE:
777: mad->host_config.common.status = cpu_to_be16(1);
778: vscsi_send_iu(s, req, sizeof(mad->host_config), VIOSRP_MAD_FORMAT);
779: break;
780: default:
781: fprintf(stderr, "VSCSI: Unknown MAD type %02x\n",
782: be32_to_cpu(mad->empty_iu.common.type));
783: }
784:
785: return 1;
786: }
787:
788: static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
789: {
790: vscsi_req *req;
791: int done;
792:
793: req = vscsi_get_req(s);
794: if (req == NULL) {
795: fprintf(stderr, "VSCSI: Failed to get a request !\n");
796: return;
797: }
798:
799: /* We only support a limited number of descriptors, we know
800: * the ibmvscsi driver uses up to 10 max, so it should fit
801: * in our 256 bytes IUs. If not we'll have to increase the size
802: * of the structure.
803: */
804: if (crq->s.IU_length > sizeof(union viosrp_iu)) {
805: fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n",
806: crq->s.IU_length);
807: return;
808: }
809:
810: /* XXX Handle failure differently ? */
811: if (spapr_tce_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
812: crq->s.IU_length)) {
813: fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
1.1.1.2 ! root 814: g_free(req);
1.1 root 815: }
816: memcpy(&req->crq, crq, sizeof(vscsi_crq));
817:
818: if (crq->s.format == VIOSRP_MAD_FORMAT) {
819: done = vscsi_handle_mad_req(s, req);
820: } else {
821: done = vscsi_handle_srp_req(s, req);
822: }
823:
824: if (done) {
825: vscsi_put_req(req);
826: }
827: }
828:
829:
830: static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)
831: {
832: VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
833: vscsi_crq crq;
834:
835: memcpy(crq.raw, crq_data, 16);
836: crq.s.timeout = be16_to_cpu(crq.s.timeout);
837: crq.s.IU_length = be16_to_cpu(crq.s.IU_length);
838: crq.s.IU_data_ptr = be64_to_cpu(crq.s.IU_data_ptr);
839:
840: dprintf("VSCSI: do_crq %02x %02x ...\n", crq.raw[0], crq.raw[1]);
841:
842: switch (crq.s.valid) {
843: case 0xc0: /* Init command/response */
844:
845: /* Respond to initialization request */
846: if (crq.s.format == 0x01) {
847: memset(crq.raw, 0, 16);
848: crq.s.valid = 0xc0;
849: crq.s.format = 0x02;
850: spapr_vio_send_crq(dev, crq.raw);
851: }
852:
853: /* Note that in hotplug cases, we might get a 0x02
854: * as a result of us emitting the init request
855: */
856:
857: break;
858: case 0xff: /* Link event */
859:
860: /* Not handled for now */
861:
862: break;
863: case 0x80: /* Payloads */
864: switch (crq.s.format) {
865: case VIOSRP_SRP_FORMAT: /* AKA VSCSI request */
866: case VIOSRP_MAD_FORMAT: /* AKA VSCSI response */
867: vscsi_got_payload(s, &crq);
868: break;
869: case VIOSRP_OS400_FORMAT:
870: case VIOSRP_AIX_FORMAT:
871: case VIOSRP_LINUX_FORMAT:
872: case VIOSRP_INLINE_FORMAT:
873: fprintf(stderr, "vscsi_do_srq: Unsupported payload format %02x\n",
874: crq.s.format);
875: break;
876: default:
877: fprintf(stderr, "vscsi_do_srq: Unknown payload format %02x\n",
878: crq.s.format);
879: }
880: break;
881: default:
882: fprintf(stderr, "vscsi_do_crq: unknown CRQ %02x %02x ...\n",
883: crq.raw[0], crq.raw[1]);
884: };
885:
886: return 0;
887: }
888:
1.1.1.2 ! root 889: static const struct SCSIBusInfo vscsi_scsi_info = {
! 890: .tcq = true,
! 891: .max_channel = 7, /* logical unit addressing format */
! 892: .max_target = 63,
! 893: .max_lun = 31,
! 894:
1.1 root 895: .transfer_data = vscsi_transfer_data,
896: .complete = vscsi_command_complete,
897: .cancel = vscsi_request_cancelled
898: };
899:
900: static int spapr_vscsi_init(VIOsPAPRDevice *dev)
901: {
902: VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
903: int i;
904:
905: dbg_vscsi_state = s;
906:
907: /* Initialize qemu request tags */
908: memset(s->reqs, 0, sizeof(s->reqs));
909: for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
910: s->reqs[i].qtag = i;
911: }
912:
913: dev->crq.SendFunc = vscsi_do_crq;
914:
1.1.1.2 ! root 915: scsi_bus_new(&s->bus, &dev->qdev, &vscsi_scsi_info);
1.1 root 916: if (!dev->qdev.hotplugged) {
917: scsi_bus_legacy_handle_cmdline(&s->bus);
918: }
919:
920: return 0;
921: }
922:
1.1.1.2 ! root 923: void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg)
1.1 root 924: {
925: DeviceState *dev;
926:
927: dev = qdev_create(&bus->bus, "spapr-vscsi");
928: qdev_prop_set_uint32(dev, "reg", reg);
929:
930: qdev_init_nofail(dev);
931: }
932:
933: static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
934: {
935: int ret;
936:
937: ret = fdt_setprop_cell(fdt, node_off, "#address-cells", 2);
938: if (ret < 0) {
939: return ret;
940: }
941:
942: ret = fdt_setprop_cell(fdt, node_off, "#size-cells", 0);
943: if (ret < 0) {
944: return ret;
945: }
946:
947: return 0;
948: }
949:
950: static VIOsPAPRDeviceInfo spapr_vscsi = {
951: .init = spapr_vscsi_init,
952: .devnode = spapr_vscsi_devnode,
953: .dt_name = "v-scsi",
954: .dt_type = "vscsi",
955: .dt_compatible = "IBM,v-scsi",
956: .signal_mask = 0x00000001,
957: .qdev.name = "spapr-vscsi",
958: .qdev.size = sizeof(VSCSIState),
959: .qdev.props = (Property[]) {
1.1.1.2 ! root 960: DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
1.1 root 961: DEFINE_PROP_END_OF_LIST(),
962: },
963: };
964:
965: static void spapr_vscsi_register(void)
966: {
967: spapr_vio_bus_register_withprop(&spapr_vscsi);
968: }
969: device_init(spapr_vscsi_register);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.