Commit 9ec76fbf7d6da3e98070a7059699d0ca019b0c9b

Authored by Matthew Wilcox
Committed by James Bottomley
1 parent 50865c1d38

[SCSI] qlogicpti: Add a slave_configure method

By configuring targets in slave_configure, we can eliminate a shadow
queuecommand, a shadow scsi_done, a write to the host template, abuse of
SCp->Message and SCp->Status, a use of kmap_atomic() and sniffing the
results of INQUIRY.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

Showing 2 changed files with 27 additions and 147 deletions Side-by-side Diff

drivers/scsi/qlogicpti.c
... ... @@ -310,8 +310,6 @@
310 310 }
311 311 qpti->dev_param[i].device_enable = 1;
312 312 }
313   - /* this is very important to set! */
314   - qpti->sbits = 1 << qpti->scsi_id;
315 313 }
316 314  
317 315 static int qlogicpti_reset_hardware(struct Scsi_Host *host)
318 316  
319 317  
320 318  
321 319  
322 320  
323 321  
324 322  
... ... @@ -951,156 +949,38 @@
951 949 host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
952 950 }
953 951  
954   -static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out)
  952 +static int qlogicpti_slave_configure(struct scsi_device *sdev)
955 953 {
956   - unsigned char *buf;
957   - unsigned int buflen;
  954 + struct qlogicpti *qpti = shost_priv(sdev->host);
  955 + int tgt = sdev->id;
  956 + u_short param[6];
958 957  
959   - if (cmd->use_sg) {
960   - struct scatterlist *sg;
961   -
962   - sg = (struct scatterlist *) cmd->request_buffer;
963   - buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
964   - buflen = sg->length;
  958 + /* tags handled in midlayer */
  959 + /* enable sync mode? */
  960 + if (sdev->sdtr) {
  961 + qpti->dev_param[tgt].device_flags |= 0x10;
965 962 } else {
966   - buf = cmd->request_buffer;
967   - buflen = cmd->request_bufflen;
  963 + qpti->dev_param[tgt].synchronous_offset = 0;
  964 + qpti->dev_param[tgt].synchronous_period = 0;
968 965 }
  966 + /* are we wide capable? */
  967 + if (sdev->wdtr)
  968 + qpti->dev_param[tgt].device_flags |= 0x20;
969 969  
970   - *buf_out = buf;
971   - return buflen;
972   -}
973   -
974   -static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf)
975   -{
976   - if (cmd->use_sg) {
977   - struct scatterlist *sg;
978   -
979   - sg = (struct scatterlist *) cmd->request_buffer;
980   - kunmap_atomic(buf - sg->offset, KM_IRQ0);
  970 + param[0] = MBOX_SET_TARGET_PARAMS;
  971 + param[1] = (tgt << 8);
  972 + param[2] = (qpti->dev_param[tgt].device_flags << 8);
  973 + if (qpti->dev_param[tgt].device_flags & 0x10) {
  974 + param[3] = (qpti->dev_param[tgt].synchronous_offset << 8) |
  975 + qpti->dev_param[tgt].synchronous_period;
  976 + } else {
  977 + param[3] = 0;
981 978 }
  979 + qlogicpti_mbox_command(qpti, param, 0);
  980 + return 0;
982 981 }
983 982  
984 983 /*
985   - * Until we scan the entire bus with inquiries, go throught this fella...
986   - */
987   -static void ourdone(struct scsi_cmnd *Cmnd)
988   -{
989   - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata;
990   - int tgt = Cmnd->device->id;
991   - void (*done) (struct scsi_cmnd *);
992   -
993   - /* This grot added by DaveM, blame him for ugliness.
994   - * The issue is that in the 2.3.x driver we use the
995   - * host_scribble portion of the scsi command as a
996   - * completion linked list at interrupt service time,
997   - * so we have to store the done function pointer elsewhere.
998   - */
999   - done = (void (*)(struct scsi_cmnd *))
1000   - (((unsigned long) Cmnd->SCp.Message)
1001   -#ifdef __sparc_v9__
1002   - | ((unsigned long) Cmnd->SCp.Status << 32UL)
1003   -#endif
1004   - );
1005   -
1006   - if ((qpti->sbits & (1 << tgt)) == 0) {
1007   - int ok = host_byte(Cmnd->result) == DID_OK;
1008   - if (Cmnd->cmnd[0] == 0x12 && ok) {
1009   - unsigned char *iqd;
1010   - unsigned int iqd_len;
1011   -
1012   - iqd_len = scsi_rbuf_get(Cmnd, &iqd);
1013   -
1014   - /* tags handled in midlayer */
1015   - /* enable sync mode? */
1016   - if (iqd[7] & 0x10) {
1017   - qpti->dev_param[tgt].device_flags |= 0x10;
1018   - } else {
1019   - qpti->dev_param[tgt].synchronous_offset = 0;
1020   - qpti->dev_param[tgt].synchronous_period = 0;
1021   - }
1022   - /* are we wide capable? */
1023   - if (iqd[7] & 0x20) {
1024   - qpti->dev_param[tgt].device_flags |= 0x20;
1025   - }
1026   -
1027   - scsi_rbuf_put(Cmnd, iqd);
1028   -
1029   - qpti->sbits |= (1 << tgt);
1030   - } else if (!ok) {
1031   - qpti->sbits |= (1 << tgt);
1032   - }
1033   - }
1034   - done(Cmnd);
1035   -}
1036   -
1037   -static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *));
1038   -
1039   -static int qlogicpti_queuecommand_slow(struct scsi_cmnd *Cmnd,
1040   - void (*done)(struct scsi_cmnd *))
1041   -{
1042   - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata;
1043   -
1044   - /*
1045   - * done checking this host adapter?
1046   - * If not, then rewrite the command
1047   - * to finish through ourdone so we
1048   - * can peek at Inquiry data results.
1049   - */
1050   - if (qpti->sbits && qpti->sbits != 0xffff) {
1051   - /* See above about in ourdone this ugliness... */
1052   - Cmnd->SCp.Message = ((unsigned long)done) & 0xffffffff;
1053   -#ifdef CONFIG_SPARC64
1054   - Cmnd->SCp.Status = ((unsigned long)done >> 32UL) & 0xffffffff;
1055   -#endif
1056   - return qlogicpti_queuecommand(Cmnd, ourdone);
1057   - }
1058   -
1059   - /*
1060   - * We've peeked at all targets for this bus- time
1061   - * to set parameters for devices for real now.
1062   - */
1063   - if (qpti->sbits == 0xffff) {
1064   - int i;
1065   - for(i = 0; i < MAX_TARGETS; i++) {
1066   - u_short param[6];
1067   - param[0] = MBOX_SET_TARGET_PARAMS;
1068   - param[1] = (i << 8);
1069   - param[2] = (qpti->dev_param[i].device_flags << 8);
1070   - if (qpti->dev_param[i].device_flags & 0x10) {
1071   - param[3] = (qpti->dev_param[i].synchronous_offset << 8) |
1072   - qpti->dev_param[i].synchronous_period;
1073   - } else {
1074   - param[3] = 0;
1075   - }
1076   - (void) qlogicpti_mbox_command(qpti, param, 0);
1077   - }
1078   - /*
1079   - * set to zero so any traverse through ourdone
1080   - * doesn't start the whole process again,
1081   - */
1082   - qpti->sbits = 0;
1083   - }
1084   -
1085   - /* check to see if we're done with all adapters... */
1086   - for (qpti = qptichain; qpti != NULL; qpti = qpti->next) {
1087   - if (qpti->sbits) {
1088   - break;
1089   - }
1090   - }
1091   -
1092   - /*
1093   - * if we hit the end of the chain w/o finding adapters still
1094   - * capability-configuring, then we're done with all adapters
1095   - * and can rock on..
1096   - */
1097   - if (qpti == NULL)
1098   - Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand;
1099   -
1100   - return qlogicpti_queuecommand(Cmnd, done);
1101   -}
1102   -
1103   -/*
1104 984 * The middle SCSI layer ensures that queuecommand never gets invoked
1105 985 * concurrently with itself or the interrupt handler (though the
1106 986 * interrupt handler may call this routine as part of
... ... @@ -1390,7 +1270,8 @@
1390 1270 .module = THIS_MODULE,
1391 1271 .name = "qlogicpti",
1392 1272 .info = qlogicpti_info,
1393   - .queuecommand = qlogicpti_queuecommand_slow,
  1273 + .queuecommand = qlogicpti_queuecommand,
  1274 + .slave_configure = qlogicpti_slave_configure,
1394 1275 .eh_abort_handler = qlogicpti_abort,
1395 1276 .eh_bus_reset_handler = qlogicpti_reset,
1396 1277 .can_queue = QLOGICPTI_REQ_QUEUE_LEN,
drivers/scsi/qlogicpti.h
... ... @@ -380,8 +380,7 @@
380 380 unsigned char swsreg;
381 381 unsigned int
382 382 gotirq : 1, /* this instance got an irq */
383   - is_pti : 1, /* Non-zero if this is a PTI board. */
384   - sbits : 16; /* syncmode known bits */
  383 + is_pti : 1; /* Non-zero if this is a PTI board. */
385 384 };
386 385  
387 386 /* How to twiddle them bits... */