Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] scsi tgt: IBM eServer i/pSeries virtual SCSI target driver

This is IBM Virtual SCSI target driver for tgt. The driver is based on
the original ibmvscsis driver:

http://lkml.org/lkml/2005/10/17/99

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Santiago Leon <santil@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

FUJITA Tomonori and committed by
James Bottomley
0e5d030b 26b14823

+975
+14
drivers/scsi/Kconfig
··· 821 821 To compile this driver as a module, choose M here: the 822 822 module will be called ibmvscsic. 823 823 824 + config SCSI_IBMVSCSIS 825 + tristate "IBM Virtual SCSI Server support" 826 + depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP 827 + help 828 + This is the SRP target driver for IBM pSeries virtual environments. 829 + 830 + The userspace component needed to initialize the driver and 831 + documentation can be found: 832 + 833 + http://stgt.berlios.de/ 834 + 835 + To compile this driver as a module, choose M here: the 836 + module will be called ibmvstgt. 837 + 824 838 config SCSI_INITIO 825 839 tristate "Initio 9100U(W) support" 826 840 depends on PCI && SCSI
+1
drivers/scsi/Makefile
··· 128 128 obj-$(CONFIG_SCSI_IPR) += ipr.o 129 129 obj-$(CONFIG_SCSI_SRP) += libsrp.o 130 130 obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ 131 + obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ 131 132 obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o 132 133 obj-$(CONFIG_SCSI_STEX) += stex.o 133 134
+2
drivers/scsi/ibmvscsi/Makefile
··· 3 3 ibmvscsic-y += ibmvscsi.o 4 4 ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o 5 5 ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o 6 + 7 + obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
+958
drivers/scsi/ibmvscsi/ibmvstgt.c
··· 1 + /* 2 + * IBM eServer i/pSeries Virtual SCSI Target Driver 3 + * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp. 4 + * Santiago Leon (santil@us.ibm.com) IBM Corp. 5 + * Linda Xie (lxie@us.ibm.com) IBM Corp. 6 + * 7 + * Copyright (C) 2005-2006 FUJITA Tomonori <tomof@acm.org> 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation; either version 2 of the License, or 12 + * (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 + * You should have received a copy of the GNU General Public License 20 + * along with this program; if not, write to the Free Software 21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 + * USA 23 + */ 24 + #include <linux/interrupt.h> 25 + #include <linux/module.h> 26 + #include <scsi/scsi.h> 27 + #include <scsi/scsi_host.h> 28 + #include <scsi/scsi_tgt.h> 29 + #include <scsi/libsrp.h> 30 + #include <asm/hvcall.h> 31 + #include <asm/iommu.h> 32 + #include <asm/prom.h> 33 + #include <asm/vio.h> 34 + 35 + #include "ibmvscsi.h" 36 + 37 + #define INITIAL_SRP_LIMIT 16 38 + #define DEFAULT_MAX_SECTORS 512 39 + 40 + #define TGT_NAME "ibmvstgt" 41 + 42 + /* 43 + * Hypervisor calls. 44 + */ 45 + #define h_copy_rdma(l, sa, sb, da, db) \ 46 + plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db) 47 + #define h_send_crq(ua, l, h) \ 48 + plpar_hcall_norets(H_SEND_CRQ, ua, l, h) 49 + #define h_reg_crq(ua, tok, sz)\ 50 + plpar_hcall_norets(H_REG_CRQ, ua, tok, sz); 51 + #define h_free_crq(ua) \ 52 + plpar_hcall_norets(H_FREE_CRQ, ua); 53 + 54 + /* tmp - will replace with SCSI logging stuff */ 55 + #define eprintk(fmt, args...) \ 56 + do { \ 57 + printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ 58 + } while (0) 59 + /* #define dprintk eprintk */ 60 + #define dprintk(fmt, args...) 61 + 62 + struct vio_port { 63 + struct vio_dev *dma_dev; 64 + 65 + struct crq_queue crq_queue; 66 + struct work_struct crq_work; 67 + 68 + unsigned long liobn; 69 + unsigned long riobn; 70 + }; 71 + 72 + static struct workqueue_struct *vtgtd; 73 + 74 + /* 75 + * These are fixed for the system and come from the Open Firmware device tree. 76 + * We just store them here to save getting them every time. 77 + */ 78 + static char system_id[64] = ""; 79 + static char partition_name[97] = "UNKNOWN"; 80 + static unsigned int partition_number = -1; 81 + 82 + static struct vio_port *target_to_port(struct srp_target *target) 83 + { 84 + return (struct vio_port *) target->ldata; 85 + } 86 + 87 + static inline union viosrp_iu *vio_iu(struct iu_entry *iue) 88 + { 89 + return (union viosrp_iu *) (iue->sbuf->buf); 90 + } 91 + 92 + static int send_iu(struct iu_entry *iue, uint64_t length, uint8_t format) 93 + { 94 + struct srp_target *target = iue->target; 95 + struct vio_port *vport = target_to_port(target); 96 + long rc, rc1; 97 + union { 98 + struct viosrp_crq cooked; 99 + uint64_t raw[2]; 100 + } crq; 101 + 102 + /* First copy the SRP */ 103 + rc = h_copy_rdma(length, vport->liobn, iue->sbuf->dma, 104 + vport->riobn, iue->remote_token); 105 + 106 + if (rc) 107 + eprintk("Error %ld transferring data\n", rc); 108 + 109 + crq.cooked.valid = 0x80; 110 + crq.cooked.format = format; 111 + crq.cooked.reserved = 0x00; 112 + crq.cooked.timeout = 0x00; 113 + crq.cooked.IU_length = length; 114 + crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag; 115 + 116 + if (rc == 0) 117 + crq.cooked.status = 0x99; /* Just needs to be non-zero */ 118 + else 119 + crq.cooked.status = 0x00; 120 + 121 + rc1 = h_send_crq(vport->dma_dev->unit_address, crq.raw[0], crq.raw[1]); 122 + 123 + if (rc1) { 124 + eprintk("%ld sending response\n", rc1); 125 + return rc1; 126 + } 127 + 128 + return rc; 129 + } 130 + 131 + #define SRP_RSP_SENSE_DATA_LEN 18 132 + 133 + static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, 134 + unsigned char status, unsigned char asc) 135 + { 136 + union viosrp_iu *iu = vio_iu(iue); 137 + uint64_t tag = iu->srp.rsp.tag; 138 + 139 + /* If the linked bit is on and status is good */ 140 + if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE)) 141 + status = 0x10; 142 + 143 + memset(iu, 0, sizeof(struct srp_rsp)); 144 + iu->srp.rsp.opcode = SRP_RSP; 145 + iu->srp.rsp.req_lim_delta = 1; 146 + iu->srp.rsp.tag = tag; 147 + 148 + if (test_bit(V_DIOVER, &iue->flags)) 149 + iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER; 150 + 151 + iu->srp.rsp.data_in_res_cnt = 0; 152 + iu->srp.rsp.data_out_res_cnt = 0; 153 + 154 + iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID; 155 + 156 + iu->srp.rsp.resp_data_len = 0; 157 + iu->srp.rsp.status = status; 158 + if (status) { 159 + uint8_t *sense = iu->srp.rsp.data; 160 + 161 + if (sc) { 162 + iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; 163 + iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE; 164 + memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE); 165 + } else { 166 + iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION; 167 + iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; 168 + iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN; 169 + 170 + /* Valid bit and 'current errors' */ 171 + sense[0] = (0x1 << 7 | 0x70); 172 + /* Sense key */ 173 + sense[2] = status; 174 + /* Additional sense length */ 175 + sense[7] = 0xa; /* 10 bytes */ 176 + /* Additional sense code */ 177 + sense[12] = asc; 178 + } 179 + } 180 + 181 + send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN, 182 + VIOSRP_SRP_FORMAT); 183 + 184 + return 0; 185 + } 186 + 187 + static void handle_cmd_queue(struct srp_target *target) 188 + { 189 + struct Scsi_Host *shost = target->shost; 190 + struct iu_entry *iue; 191 + struct srp_cmd *cmd; 192 + unsigned long flags; 193 + int err; 194 + 195 + retry: 196 + spin_lock_irqsave(&target->lock, flags); 197 + 198 + list_for_each_entry(iue, &target->cmd_queue, ilist) { 199 + if (!test_and_set_bit(V_FLYING, &iue->flags)) { 200 + spin_unlock_irqrestore(&target->lock, flags); 201 + cmd = iue->sbuf->buf; 202 + err = srp_cmd_queue(shost, cmd, iue, 0); 203 + if (err) { 204 + eprintk("cannot queue cmd %p %d\n", cmd, err); 205 + srp_iu_put(iue); 206 + } 207 + goto retry; 208 + } 209 + } 210 + 211 + spin_unlock_irqrestore(&target->lock, flags); 212 + } 213 + 214 + static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, 215 + struct srp_direct_buf *md, int nmd, 216 + enum dma_data_direction dir, unsigned int rest) 217 + { 218 + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; 219 + struct srp_target *target = iue->target; 220 + struct vio_port *vport = target_to_port(target); 221 + dma_addr_t token; 222 + long err; 223 + unsigned int done = 0; 224 + int i, sidx, soff; 225 + 226 + sidx = soff = 0; 227 + token = sg_dma_address(sg + sidx); 228 + 229 + for (i = 0; i < nmd && rest; i++) { 230 + unsigned int mdone, mlen; 231 + 232 + mlen = min(rest, md[i].len); 233 + for (mdone = 0; mlen;) { 234 + int slen = min(sg_dma_len(sg + sidx) - soff, mlen); 235 + 236 + if (dir == DMA_TO_DEVICE) 237 + err = h_copy_rdma(slen, 238 + vport->riobn, 239 + md[i].va + mdone, 240 + vport->liobn, 241 + token + soff); 242 + else 243 + err = h_copy_rdma(slen, 244 + vport->liobn, 245 + token + soff, 246 + vport->riobn, 247 + md[i].va + mdone); 248 + 249 + if (err != H_SUCCESS) { 250 + eprintk("rdma error %d %d\n", dir, slen); 251 + goto out; 252 + } 253 + 254 + mlen -= slen; 255 + mdone += slen; 256 + soff += slen; 257 + done += slen; 258 + 259 + if (soff == sg_dma_len(sg + sidx)) { 260 + sidx++; 261 + soff = 0; 262 + token = sg_dma_address(sg + sidx); 263 + 264 + if (sidx > nsg) { 265 + eprintk("out of sg %p %d %d\n", 266 + iue, sidx, nsg); 267 + goto out; 268 + } 269 + } 270 + }; 271 + 272 + rest -= mlen; 273 + } 274 + out: 275 + 276 + return 0; 277 + } 278 + 279 + static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, 280 + void (*done)(struct scsi_cmnd *)) 281 + { 282 + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; 283 + int err; 284 + 285 + err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); 286 + 287 + done(sc); 288 + 289 + return err; 290 + } 291 + 292 + static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, 293 + void (*done)(struct scsi_cmnd *)) 294 + { 295 + unsigned long flags; 296 + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; 297 + struct srp_target *target = iue->target; 298 + 299 + dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); 300 + 301 + spin_lock_irqsave(&target->lock, flags); 302 + list_del(&iue->ilist); 303 + spin_unlock_irqrestore(&target->lock, flags); 304 + 305 + if (sc->result != SAM_STAT_GOOD) { 306 + eprintk("operation failed %p %d %x\n", 307 + iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]); 308 + send_rsp(iue, sc, HARDWARE_ERROR, 0x00); 309 + } else 310 + send_rsp(iue, sc, NO_SENSE, 0x00); 311 + 312 + done(sc); 313 + srp_iu_put(iue); 314 + return 0; 315 + } 316 + 317 + int send_adapter_info(struct iu_entry *iue, 318 + dma_addr_t remote_buffer, uint16_t length) 319 + { 320 + struct srp_target *target = iue->target; 321 + struct vio_port *vport = target_to_port(target); 322 + struct Scsi_Host *shost = target->shost; 323 + dma_addr_t data_token; 324 + struct mad_adapter_info_data *info; 325 + int err; 326 + 327 + info = dma_alloc_coherent(target->dev, sizeof(*info), &data_token, 328 + GFP_KERNEL); 329 + if (!info) { 330 + eprintk("bad dma_alloc_coherent %p\n", target); 331 + return 1; 332 + } 333 + 334 + /* Get remote info */ 335 + err = h_copy_rdma(sizeof(*info), vport->riobn, remote_buffer, 336 + vport->liobn, data_token); 337 + if (err == H_SUCCESS) { 338 + dprintk("Client connect: %s (%d)\n", 339 + info->partition_name, info->partition_number); 340 + } 341 + 342 + memset(info, 0, sizeof(*info)); 343 + 344 + strcpy(info->srp_version, "16.a"); 345 + strncpy(info->partition_name, partition_name, 346 + sizeof(info->partition_name)); 347 + info->partition_number = partition_number; 348 + info->mad_version = 1; 349 + info->os_type = 2; 350 + info->port_max_txu[0] = shost->hostt->max_sectors << 9; 351 + 352 + /* Send our info to remote */ 353 + err = h_copy_rdma(sizeof(*info), vport->liobn, data_token, 354 + vport->riobn, remote_buffer); 355 + 356 + dma_free_coherent(target->dev, sizeof(*info), info, data_token); 357 + 358 + if (err != H_SUCCESS) { 359 + eprintk("Error sending adapter info %d\n", err); 360 + return 1; 361 + } 362 + 363 + return 0; 364 + } 365 + 366 + static void process_login(struct iu_entry *iue) 367 + { 368 + union viosrp_iu *iu = vio_iu(iue); 369 + struct srp_login_rsp *rsp = &iu->srp.login_rsp; 370 + uint64_t tag = iu->srp.rsp.tag; 371 + 372 + /* TODO handle case that requested size is wrong and 373 + * buffer format is wrong 374 + */ 375 + memset(iu, 0, sizeof(struct srp_login_rsp)); 376 + rsp->opcode = SRP_LOGIN_RSP; 377 + rsp->req_lim_delta = INITIAL_SRP_LIMIT; 378 + rsp->tag = tag; 379 + rsp->max_it_iu_len = sizeof(union srp_iu); 380 + rsp->max_ti_iu_len = sizeof(union srp_iu); 381 + /* direct and indirect */ 382 + rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT; 383 + 384 + send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT); 385 + } 386 + 387 + static inline void queue_cmd(struct iu_entry *iue) 388 + { 389 + struct srp_target *target = iue->target; 390 + unsigned long flags; 391 + 392 + spin_lock_irqsave(&target->lock, flags); 393 + list_add_tail(&iue->ilist, &target->cmd_queue); 394 + spin_unlock_irqrestore(&target->lock, flags); 395 + } 396 + 397 + static int process_tsk_mgmt(struct iu_entry *iue) 398 + { 399 + union viosrp_iu *iu = vio_iu(iue); 400 + int fn; 401 + 402 + dprintk("%p %u\n", iue, iu->srp.tsk_mgmt.tsk_mgmt_func); 403 + 404 + switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { 405 + case SRP_TSK_ABORT_TASK: 406 + fn = ABORT_TASK; 407 + break; 408 + case SRP_TSK_ABORT_TASK_SET: 409 + fn = ABORT_TASK_SET; 410 + break; 411 + case SRP_TSK_CLEAR_TASK_SET: 412 + fn = CLEAR_TASK_SET; 413 + break; 414 + case SRP_TSK_LUN_RESET: 415 + fn = LOGICAL_UNIT_RESET; 416 + break; 417 + case SRP_TSK_CLEAR_ACA: 418 + fn = CLEAR_ACA; 419 + break; 420 + default: 421 + fn = 0; 422 + } 423 + if (fn) 424 + scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, 425 + iu->srp.tsk_mgmt.task_tag, 426 + (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, 427 + iue); 428 + else 429 + send_rsp(iue, NULL, ILLEGAL_REQUEST, 0x20); 430 + 431 + return !fn; 432 + } 433 + 434 + static int process_mad_iu(struct iu_entry *iue) 435 + { 436 + union viosrp_iu *iu = vio_iu(iue); 437 + struct viosrp_adapter_info *info; 438 + struct viosrp_host_config *conf; 439 + 440 + switch (iu->mad.empty_iu.common.type) { 441 + case VIOSRP_EMPTY_IU_TYPE: 442 + eprintk("%s\n", "Unsupported EMPTY MAD IU"); 443 + break; 444 + case VIOSRP_ERROR_LOG_TYPE: 445 + eprintk("%s\n", "Unsupported ERROR LOG MAD IU"); 446 + iu->mad.error_log.common.status = 1; 447 + send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT); 448 + break; 449 + case VIOSRP_ADAPTER_INFO_TYPE: 450 + info = &iu->mad.adapter_info; 451 + info->common.status = send_adapter_info(iue, info->buffer, 452 + info->common.length); 453 + send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT); 454 + break; 455 + case VIOSRP_HOST_CONFIG_TYPE: 456 + conf = &iu->mad.host_config; 457 + conf->common.status = 1; 458 + send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT); 459 + break; 460 + default: 461 + eprintk("Unknown type %u\n", iu->srp.rsp.opcode); 462 + } 463 + 464 + return 1; 465 + } 466 + 467 + static int process_srp_iu(struct iu_entry *iue) 468 + { 469 + union viosrp_iu *iu = vio_iu(iue); 470 + int done = 1; 471 + u8 opcode = iu->srp.rsp.opcode; 472 + 473 + switch (opcode) { 474 + case SRP_LOGIN_REQ: 475 + process_login(iue); 476 + break; 477 + case SRP_TSK_MGMT: 478 + done = process_tsk_mgmt(iue); 479 + break; 480 + case SRP_CMD: 481 + queue_cmd(iue); 482 + done = 0; 483 + break; 484 + case SRP_LOGIN_RSP: 485 + case SRP_I_LOGOUT: 486 + case SRP_T_LOGOUT: 487 + case SRP_RSP: 488 + case SRP_CRED_REQ: 489 + case SRP_CRED_RSP: 490 + case SRP_AER_REQ: 491 + case SRP_AER_RSP: 492 + eprintk("Unsupported type %u\n", opcode); 493 + break; 494 + default: 495 + eprintk("Unknown type %u\n", opcode); 496 + } 497 + 498 + return done; 499 + } 500 + 501 + static void process_iu(struct viosrp_crq *crq, struct srp_target *target) 502 + { 503 + struct vio_port *vport = target_to_port(target); 504 + struct iu_entry *iue; 505 + long err, done; 506 + 507 + iue = srp_iu_get(target); 508 + if (!iue) { 509 + eprintk("Error getting IU from pool, %p\n", target); 510 + return; 511 + } 512 + 513 + iue->remote_token = crq->IU_data_ptr; 514 + 515 + err = h_copy_rdma(crq->IU_length, vport->riobn, 516 + iue->remote_token, vport->liobn, iue->sbuf->dma); 517 + 518 + if (err != H_SUCCESS) { 519 + eprintk("%ld transferring data error %p\n", err, iue); 520 + done = 1; 521 + goto out; 522 + } 523 + 524 + if (crq->format == VIOSRP_MAD_FORMAT) 525 + done = process_mad_iu(iue); 526 + else 527 + done = process_srp_iu(iue); 528 + out: 529 + if (done) 530 + srp_iu_put(iue); 531 + } 532 + 533 + static irqreturn_t ibmvstgt_interrupt(int irq, void *data) 534 + { 535 + struct srp_target *target = (struct srp_target *) data; 536 + struct vio_port *vport = target_to_port(target); 537 + 538 + vio_disable_interrupts(vport->dma_dev); 539 + queue_work(vtgtd, &vport->crq_work); 540 + 541 + return IRQ_HANDLED; 542 + } 543 + 544 + static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) 545 + { 546 + int err; 547 + struct vio_port *vport = target_to_port(target); 548 + 549 + queue->msgs = (struct viosrp_crq *) get_zeroed_page(GFP_KERNEL); 550 + if (!queue->msgs) 551 + goto malloc_failed; 552 + queue->size = PAGE_SIZE / sizeof(*queue->msgs); 553 + 554 + queue->msg_token = dma_map_single(target->dev, queue->msgs, 555 + queue->size * sizeof(*queue->msgs), 556 + DMA_BIDIRECTIONAL); 557 + 558 + if (dma_mapping_error(queue->msg_token)) 559 + goto map_failed; 560 + 561 + err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, 562 + PAGE_SIZE); 563 + 564 + /* If the adapter was left active for some reason (like kexec) 565 + * try freeing and re-registering 566 + */ 567 + if (err == H_RESOURCE) { 568 + do { 569 + err = h_free_crq(vport->dma_dev->unit_address); 570 + } while (err == H_BUSY || H_IS_LONG_BUSY(err)); 571 + 572 + err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, 573 + PAGE_SIZE); 574 + } 575 + 576 + if (err != H_SUCCESS && err != 2) { 577 + eprintk("Error 0x%x opening virtual adapter\n", err); 578 + goto reg_crq_failed; 579 + } 580 + 581 + err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt, 582 + SA_INTERRUPT, "ibmvstgt", target); 583 + if (err) 584 + goto req_irq_failed; 585 + 586 + vio_enable_interrupts(vport->dma_dev); 587 + 588 + h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0); 589 + 590 + queue->cur = 0; 591 + spin_lock_init(&queue->lock); 592 + 593 + return 0; 594 + 595 + req_irq_failed: 596 + do { 597 + err = h_free_crq(vport->dma_dev->unit_address); 598 + } while (err == H_BUSY || H_IS_LONG_BUSY(err)); 599 + 600 + reg_crq_failed: 601 + dma_unmap_single(target->dev, queue->msg_token, 602 + queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); 603 + map_failed: 604 + free_page((unsigned long) queue->msgs); 605 + 606 + malloc_failed: 607 + return -ENOMEM; 608 + } 609 + 610 + static void crq_queue_destroy(struct srp_target *target) 611 + { 612 + struct vio_port *vport = target_to_port(target); 613 + struct crq_queue *queue = &vport->crq_queue; 614 + int err; 615 + 616 + free_irq(vport->dma_dev->irq, target); 617 + do { 618 + err = h_free_crq(vport->dma_dev->unit_address); 619 + } while (err == H_BUSY || H_IS_LONG_BUSY(err)); 620 + 621 + dma_unmap_single(target->dev, queue->msg_token, 622 + queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); 623 + 624 + free_page((unsigned long) queue->msgs); 625 + } 626 + 627 + static void process_crq(struct viosrp_crq *crq, struct srp_target *target) 628 + { 629 + struct vio_port *vport = target_to_port(target); 630 + dprintk("%x %x\n", crq->valid, crq->format); 631 + 632 + switch (crq->valid) { 633 + case 0xC0: 634 + /* initialization */ 635 + switch (crq->format) { 636 + case 0x01: 637 + h_send_crq(vport->dma_dev->unit_address, 638 + 0xC002000000000000, 0); 639 + break; 640 + case 0x02: 641 + break; 642 + default: 643 + eprintk("Unknown format %u\n", crq->format); 644 + } 645 + break; 646 + case 0xFF: 647 + /* transport event */ 648 + break; 649 + case 0x80: 650 + /* real payload */ 651 + switch (crq->format) { 652 + case VIOSRP_SRP_FORMAT: 653 + case VIOSRP_MAD_FORMAT: 654 + process_iu(crq, target); 655 + break; 656 + case VIOSRP_OS400_FORMAT: 657 + case VIOSRP_AIX_FORMAT: 658 + case VIOSRP_LINUX_FORMAT: 659 + case VIOSRP_INLINE_FORMAT: 660 + eprintk("Unsupported format %u\n", crq->format); 661 + break; 662 + default: 663 + eprintk("Unknown format %u\n", crq->format); 664 + } 665 + break; 666 + default: 667 + eprintk("unknown message type 0x%02x!?\n", crq->valid); 668 + } 669 + } 670 + 671 + static inline struct viosrp_crq *next_crq(struct crq_queue *queue) 672 + { 673 + struct viosrp_crq *crq; 674 + unsigned long flags; 675 + 676 + spin_lock_irqsave(&queue->lock, flags); 677 + crq = &queue->msgs[queue->cur]; 678 + if (crq->valid & 0x80) { 679 + if (++queue->cur == queue->size) 680 + queue->cur = 0; 681 + } else 682 + crq = NULL; 683 + spin_unlock_irqrestore(&queue->lock, flags); 684 + 685 + return crq; 686 + } 687 + 688 + static void handle_crq(void *data) 689 + { 690 + struct srp_target *target = (struct srp_target *) data; 691 + struct vio_port *vport = target_to_port(target); 692 + struct viosrp_crq *crq; 693 + int done = 0; 694 + 695 + while (!done) { 696 + while ((crq = next_crq(&vport->crq_queue)) != NULL) { 697 + process_crq(crq, target); 698 + crq->valid = 0x00; 699 + } 700 + 701 + vio_enable_interrupts(vport->dma_dev); 702 + 703 + crq = next_crq(&vport->crq_queue); 704 + if (crq) { 705 + vio_disable_interrupts(vport->dma_dev); 706 + process_crq(crq, target); 707 + crq->valid = 0x00; 708 + } else 709 + done = 1; 710 + } 711 + 712 + handle_cmd_queue(target); 713 + } 714 + 715 + 716 + static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) 717 + { 718 + unsigned long flags; 719 + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; 720 + struct srp_target *target = iue->target; 721 + 722 + dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); 723 + 724 + spin_lock_irqsave(&target->lock, flags); 725 + list_del(&iue->ilist); 726 + spin_unlock_irqrestore(&target->lock, flags); 727 + 728 + srp_iu_put(iue); 729 + 730 + return 0; 731 + } 732 + 733 + static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) 734 + { 735 + struct iu_entry *iue = (struct iu_entry *) ((void *) mid); 736 + union viosrp_iu *iu = vio_iu(iue); 737 + unsigned char status, asc; 738 + 739 + eprintk("%p %d\n", iue, result); 740 + status = NO_SENSE; 741 + asc = 0; 742 + 743 + switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { 744 + case SRP_TSK_ABORT_TASK: 745 + asc = 0x14; 746 + if (result) 747 + status = ABORTED_COMMAND; 748 + break; 749 + default: 750 + break; 751 + } 752 + 753 + send_rsp(iue, NULL, status, asc); 754 + srp_iu_put(iue); 755 + 756 + return 0; 757 + } 758 + 759 + static ssize_t system_id_show(struct class_device *cdev, char *buf) 760 + { 761 + return snprintf(buf, PAGE_SIZE, "%s\n", system_id); 762 + } 763 + 764 + static ssize_t partition_number_show(struct class_device *cdev, char *buf) 765 + { 766 + return snprintf(buf, PAGE_SIZE, "%x\n", partition_number); 767 + } 768 + 769 + static ssize_t unit_address_show(struct class_device *cdev, char *buf) 770 + { 771 + struct Scsi_Host *shost = class_to_shost(cdev); 772 + struct srp_target *target = host_to_srp_target(shost); 773 + struct vio_port *vport = target_to_port(target); 774 + return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address); 775 + } 776 + 777 + static CLASS_DEVICE_ATTR(system_id, S_IRUGO, system_id_show, NULL); 778 + static CLASS_DEVICE_ATTR(partition_number, S_IRUGO, partition_number_show, NULL); 779 + static CLASS_DEVICE_ATTR(unit_address, S_IRUGO, unit_address_show, NULL); 780 + 781 + static struct class_device_attribute *ibmvstgt_attrs[] = { 782 + &class_device_attr_system_id, 783 + &class_device_attr_partition_number, 784 + &class_device_attr_unit_address, 785 + NULL, 786 + }; 787 + 788 + static struct scsi_host_template ibmvstgt_sht = { 789 + .name = TGT_NAME, 790 + .module = THIS_MODULE, 791 + .can_queue = INITIAL_SRP_LIMIT, 792 + .sg_tablesize = SG_ALL, 793 + .use_clustering = DISABLE_CLUSTERING, 794 + .max_sectors = DEFAULT_MAX_SECTORS, 795 + .transfer_response = ibmvstgt_cmd_done, 796 + .transfer_data = ibmvstgt_transfer_data, 797 + .eh_abort_handler = ibmvstgt_eh_abort_handler, 798 + .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, 799 + .shost_attrs = ibmvstgt_attrs, 800 + .proc_name = TGT_NAME, 801 + }; 802 + 803 + static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) 804 + { 805 + struct Scsi_Host *shost; 806 + struct srp_target *target; 807 + struct vio_port *vport; 808 + unsigned int *dma, dma_size; 809 + int err = -ENOMEM; 810 + 811 + vport = kzalloc(sizeof(struct vio_port), GFP_KERNEL); 812 + if (!vport) 813 + return err; 814 + shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); 815 + if (!shost) 816 + goto free_vport; 817 + err = scsi_tgt_alloc_queue(shost); 818 + if (err) 819 + goto put_host; 820 + 821 + target = host_to_srp_target(shost); 822 + target->shost = shost; 823 + vport->dma_dev = dev; 824 + target->ldata = vport; 825 + err = srp_target_alloc(target, &dev->dev, INITIAL_SRP_LIMIT, 826 + SRP_MAX_IU_LEN); 827 + if (err) 828 + goto put_host; 829 + 830 + dma = (unsigned int *) vio_get_attribute(dev, "ibm,my-dma-window", 831 + &dma_size); 832 + if (!dma || dma_size != 40) { 833 + eprintk("Couldn't get window property %d\n", dma_size); 834 + err = -EIO; 835 + goto free_srp_target; 836 + } 837 + vport->liobn = dma[0]; 838 + vport->riobn = dma[5]; 839 + 840 + INIT_WORK(&vport->crq_work, handle_crq, target); 841 + 842 + err = crq_queue_create(&vport->crq_queue, target); 843 + if (err) 844 + goto free_srp_target; 845 + 846 + err = scsi_add_host(shost, target->dev); 847 + if (err) 848 + goto destroy_queue; 849 + return 0; 850 + 851 + destroy_queue: 852 + crq_queue_destroy(target); 853 + free_srp_target: 854 + srp_target_free(target); 855 + put_host: 856 + scsi_host_put(shost); 857 + free_vport: 858 + kfree(vport); 859 + return err; 860 + } 861 + 862 + static int ibmvstgt_remove(struct vio_dev *dev) 863 + { 864 + struct srp_target *target = (struct srp_target *) dev->dev.driver_data; 865 + struct Scsi_Host *shost = target->shost; 866 + struct vio_port *vport = target->ldata; 867 + 868 + crq_queue_destroy(target); 869 + scsi_remove_host(shost); 870 + scsi_tgt_free_queue(shost); 871 + srp_target_free(target); 872 + kfree(vport); 873 + scsi_host_put(shost); 874 + return 0; 875 + } 876 + 877 + static struct vio_device_id ibmvstgt_device_table[] __devinitdata = { 878 + {"v-scsi-host", "IBM,v-scsi-host"}, 879 + {"",""} 880 + }; 881 + 882 + MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table); 883 + 884 + static struct vio_driver ibmvstgt_driver = { 885 + .id_table = ibmvstgt_device_table, 886 + .probe = ibmvstgt_probe, 887 + .remove = ibmvstgt_remove, 888 + .driver = { 889 + .name = "ibmvscsis", 890 + .owner = THIS_MODULE, 891 + } 892 + }; 893 + 894 + static int get_system_info(void) 895 + { 896 + struct device_node *rootdn; 897 + const char *id, *model, *name; 898 + unsigned int *num; 899 + 900 + rootdn = find_path_device("/"); 901 + if (!rootdn) 902 + return -ENOENT; 903 + 904 + model = get_property(rootdn, "model", NULL); 905 + id = get_property(rootdn, "system-id", NULL); 906 + if (model && id) 907 + snprintf(system_id, sizeof(system_id), "%s-%s", model, id); 908 + 909 + name = get_property(rootdn, "ibm,partition-name", NULL); 910 + if (name) 911 + strncpy(partition_name, name, sizeof(partition_name)); 912 + 913 + num = (unsigned int *) get_property(rootdn, "ibm,partition-no", NULL); 914 + if (num) 915 + partition_number = *num; 916 + 917 + return 0; 918 + } 919 + 920 + static int ibmvstgt_init(void) 921 + { 922 + int err = -ENOMEM; 923 + 924 + printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); 925 + 926 + vtgtd = create_workqueue("ibmvtgtd"); 927 + if (!vtgtd) 928 + return err; 929 + 930 + err = get_system_info(); 931 + if (err) 932 + goto destroy_wq; 933 + 934 + err = vio_register_driver(&ibmvstgt_driver); 935 + if (err) 936 + goto destroy_wq; 937 + 938 + return 0; 939 + 940 + destroy_wq: 941 + destroy_workqueue(vtgtd); 942 + return err; 943 + } 944 + 945 + static void ibmvstgt_exit(void) 946 + { 947 + printk("Unregister IBM virtual SCSI driver\n"); 948 + 949 + destroy_workqueue(vtgtd); 950 + vio_unregister_driver(&ibmvstgt_driver); 951 + } 952 + 953 + MODULE_DESCRIPTION("IBM Virtual SCSI Target"); 954 + MODULE_AUTHOR("Santiago Leon"); 955 + MODULE_LICENSE("GPL"); 956 + 957 + module_init(ibmvstgt_init); 958 + module_exit(ibmvstgt_exit);