diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2007-10-02 17:14:39 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:56:05 -0400 |
commit | 3058d5de47ce09ac0e531290566937c7d94d0653 (patch) | |
tree | c8a6a5326370b492bdb45f9c698aa6cba7342763 /drivers/scsi/gdth.c | |
parent | 884f7fba09646714f94d945162e698f0822a6fdd (diff) |
[SCSI] gdth: Setup proper per-command private data
- scsi_cmnd and specifically ->SCp of, where heavily abused
with internal meaning members and flags. So introduce a new
struct gdth_cmndinfo, put it on ->host_scribble and define a
gdth_cmnd_priv() accessor to retrieve it from a scsi_cmnd.
- The structure now holds two members:
internal_command - replaces the IS_GDTH_INTERNAL_CMD() croft.
sense_paddr - which was a 64-bit spanning on 2 32-bit members of SCp.
More overloaded members from SCp and scsi_cmnd will be moved in a later
patch (For easy review).
- Split up gdth_queuecommand to an additional internal_function. The later
is the one called by gdth_execute(). This will be more evident later in
the scsi accessors patch, but it also facilitates in the differentiation
between internal_command and external. And the setup of gdth_cmndinfo of
each command.
Signed-off-by Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r-- | drivers/scsi/gdth.c | 111 |
1 files changed, 77 insertions, 34 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 4248b041c9b5..e002c391e0d2 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -86,8 +86,8 @@ | |||
86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: | 86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: |
87 | * ptr: Chaining | 87 | * ptr: Chaining |
88 | * this_residual: Command priority | 88 | * this_residual: Command priority |
89 | * buffer: phys. DMA sense buffer | 89 | * buffer: unused |
90 | * dma_handle: phys. DMA buffer (kernel >= 2.4.0) | 90 | * dma_handle: will drop in !use_sg patch. |
91 | * buffers_residual: Timeout value | 91 | * buffers_residual: Timeout value |
92 | * Status: Command status (gdth_do_cmd()), DMA mem. mappings | 92 | * Status: Command status (gdth_do_cmd()), DMA mem. mappings |
93 | * Message: Additional info (gdth_do_cmd()), DMA direction | 93 | * Message: Additional info (gdth_do_cmd()), DMA direction |
@@ -184,6 +184,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
184 | static void gdth_flush(gdth_ha_str *ha); | 184 | static void gdth_flush(gdth_ha_str *ha); |
185 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); | 185 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); |
186 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); | 186 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); |
187 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
188 | struct gdth_cmndinfo *cmndinfo); | ||
187 | static void gdth_scsi_done(struct scsi_cmnd *scp); | 189 | static void gdth_scsi_done(struct scsi_cmnd *scp); |
188 | 190 | ||
189 | #ifdef DEBUG_GDTH | 191 | #ifdef DEBUG_GDTH |
@@ -371,9 +373,6 @@ static const struct file_operations gdth_fops = { | |||
371 | .release = gdth_close, | 373 | .release = gdth_close, |
372 | }; | 374 | }; |
373 | 375 | ||
374 | #define GDTH_MAGIC 0xc2e7c389 /* I got it from /dev/urandom */ | ||
375 | #define IS_GDTH_INTERNAL_CMD(scp) (scp->underflow == GDTH_MAGIC) | ||
376 | |||
377 | #include "gdth_proc.h" | 376 | #include "gdth_proc.h" |
378 | #include "gdth_proc.c" | 377 | #include "gdth_proc.c" |
379 | 378 | ||
@@ -394,6 +393,34 @@ static gdth_ha_str *gdth_find_ha(int hanum) | |||
394 | return NULL; | 393 | return NULL; |
395 | } | 394 | } |
396 | 395 | ||
396 | static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) | ||
397 | { | ||
398 | struct gdth_cmndinfo *priv = NULL; | ||
399 | ulong flags; | ||
400 | int i; | ||
401 | |||
402 | spin_lock_irqsave(&ha->smp_lock, flags); | ||
403 | |||
404 | for (i=0; i<GDTH_MAXCMDS; ++i) { | ||
405 | if (ha->cmndinfo[i].index == 0) { | ||
406 | priv = &ha->cmndinfo[i]; | ||
407 | priv->index = i+1; | ||
408 | memset(priv, 0, sizeof(*priv)); | ||
409 | break; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | spin_unlock_irqrestore(&ha->smp_lock, flags); | ||
414 | |||
415 | return priv; | ||
416 | } | ||
417 | |||
418 | static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) | ||
419 | { | ||
420 | BUG_ON(!priv); | ||
421 | priv->index = 0; | ||
422 | } | ||
423 | |||
397 | static void gdth_delay(int milliseconds) | 424 | static void gdth_delay(int milliseconds) |
398 | { | 425 | { |
399 | if (milliseconds == 0) { | 426 | if (milliseconds == 0) { |
@@ -405,9 +432,15 @@ static void gdth_delay(int milliseconds) | |||
405 | 432 | ||
406 | static void gdth_scsi_done(struct scsi_cmnd *scp) | 433 | static void gdth_scsi_done(struct scsi_cmnd *scp) |
407 | { | 434 | { |
435 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
436 | int internal_command = cmndinfo->internal_command; | ||
437 | |||
408 | TRACE2(("gdth_scsi_done()\n")); | 438 | TRACE2(("gdth_scsi_done()\n")); |
409 | 439 | ||
410 | if (IS_GDTH_INTERNAL_CMD(scp)) | 440 | gdth_put_cmndinfo(cmndinfo); |
441 | scp->host_scribble = NULL; | ||
442 | |||
443 | if (internal_command) | ||
411 | complete((struct completion *)scp->request); | 444 | complete((struct completion *)scp->request); |
412 | else | 445 | else |
413 | scp->scsi_done(scp); | 446 | scp->scsi_done(scp); |
@@ -416,7 +449,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp) | |||
416 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | 449 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, |
417 | int timeout, u32 *info) | 450 | int timeout, u32 *info) |
418 | { | 451 | { |
452 | gdth_ha_str *ha = shost_priv(sdev->host); | ||
419 | Scsi_Cmnd *scp; | 453 | Scsi_Cmnd *scp; |
454 | struct gdth_cmndinfo cmndinfo; | ||
420 | DECLARE_COMPLETION_ONSTACK(wait); | 455 | DECLARE_COMPLETION_ONSTACK(wait); |
421 | int rval; | 456 | int rval; |
422 | 457 | ||
@@ -425,6 +460,8 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | |||
425 | return -ENOMEM; | 460 | return -ENOMEM; |
426 | 461 | ||
427 | scp->device = sdev; | 462 | scp->device = sdev; |
463 | memset(&cmndinfo, 0, sizeof(cmndinfo)); | ||
464 | |||
428 | /* use request field to save the ptr. to completion struct. */ | 465 | /* use request field to save the ptr. to completion struct. */ |
429 | scp->request = (struct request *)&wait; | 466 | scp->request = (struct request *)&wait; |
430 | scp->timeout_per_command = timeout*HZ; | 467 | scp->timeout_per_command = timeout*HZ; |
@@ -432,8 +469,11 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | |||
432 | scp->cmd_len = 12; | 469 | scp->cmd_len = 12; |
433 | memcpy(scp->cmnd, cmnd, 12); | 470 | memcpy(scp->cmnd, cmnd, 12); |
434 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | 471 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ |
435 | scp->underflow = GDTH_MAGIC; | 472 | cmndinfo.internal_command = 1; |
436 | gdth_queuecommand(scp, NULL); | 473 | |
474 | TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); | ||
475 | __gdth_queuecommand(ha, scp, &cmndinfo); | ||
476 | |||
437 | wait_for_completion(&wait); | 477 | wait_for_completion(&wait); |
438 | 478 | ||
439 | rval = scp->SCp.Status; | 479 | rval = scp->SCp.Status; |
@@ -1966,6 +2006,7 @@ static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) | |||
1966 | 2006 | ||
1967 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) | 2007 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) |
1968 | { | 2008 | { |
2009 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
1969 | register Scsi_Cmnd *pscp; | 2010 | register Scsi_Cmnd *pscp; |
1970 | register Scsi_Cmnd *nscp; | 2011 | register Scsi_Cmnd *nscp; |
1971 | ulong flags; | 2012 | ulong flags; |
@@ -1974,7 +2015,7 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) | |||
1974 | TRACE(("gdth_putq() priority %d\n",priority)); | 2015 | TRACE(("gdth_putq() priority %d\n",priority)); |
1975 | spin_lock_irqsave(&ha->smp_lock, flags); | 2016 | spin_lock_irqsave(&ha->smp_lock, flags); |
1976 | 2017 | ||
1977 | if (!IS_GDTH_INTERNAL_CMD(scp)) { | 2018 | if (!cmndinfo->internal_command) { |
1978 | scp->SCp.this_residual = (int)priority; | 2019 | scp->SCp.this_residual = (int)priority; |
1979 | b = scp->device->channel; | 2020 | b = scp->device->channel; |
1980 | t = scp->device->id; | 2021 | t = scp->device->id; |
@@ -2035,7 +2076,7 @@ static void gdth_next(gdth_ha_str *ha) | |||
2035 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { | 2076 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { |
2036 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) | 2077 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) |
2037 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2078 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2038 | if (!IS_GDTH_INTERNAL_CMD(nscp)) { | 2079 | if (!gdth_cmnd_priv(nscp)->internal_command) { |
2039 | b = nscp->device->channel; | 2080 | b = nscp->device->channel; |
2040 | t = nscp->device->id; | 2081 | t = nscp->device->id; |
2041 | l = nscp->device->lun; | 2082 | l = nscp->device->lun; |
@@ -2060,7 +2101,7 @@ static void gdth_next(gdth_ha_str *ha) | |||
2060 | firsttime = FALSE; | 2101 | firsttime = FALSE; |
2061 | } | 2102 | } |
2062 | 2103 | ||
2063 | if (!IS_GDTH_INTERNAL_CMD(nscp)) { | 2104 | if (!gdth_cmnd_priv(nscp)->internal_command) { |
2064 | if (nscp->SCp.phase == -1) { | 2105 | if (nscp->SCp.phase == -1) { |
2065 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ | 2106 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ |
2066 | if (nscp->cmnd[0] == TEST_UNIT_READY) { | 2107 | if (nscp->cmnd[0] == TEST_UNIT_READY) { |
@@ -2123,7 +2164,7 @@ static void gdth_next(gdth_ha_str *ha) | |||
2123 | else | 2164 | else |
2124 | gdth_scsi_done(nscp); | 2165 | gdth_scsi_done(nscp); |
2125 | } | 2166 | } |
2126 | } else if (IS_GDTH_INTERNAL_CMD(nscp)) { | 2167 | } else if (gdth_cmnd_priv(nscp)->internal_command) { |
2127 | if (!(cmd_index=gdth_special_cmd(ha, nscp))) | 2168 | if (!(cmd_index=gdth_special_cmd(ha, nscp))) |
2128 | this_cmd = FALSE; | 2169 | this_cmd = FALSE; |
2129 | next_cmd = FALSE; | 2170 | next_cmd = FALSE; |
@@ -2622,6 +2663,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2622 | unchar t,l; | 2663 | unchar t,l; |
2623 | struct page *page; | 2664 | struct page *page; |
2624 | ulong offset; | 2665 | ulong offset; |
2666 | struct gdth_cmndinfo *cmndinfo; | ||
2625 | 2667 | ||
2626 | t = scp->device->id; | 2668 | t = scp->device->id; |
2627 | l = scp->device->lun; | 2669 | l = scp->device->lun; |
@@ -2645,6 +2687,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2645 | if (ha->cmd_cnt == 0) | 2687 | if (ha->cmd_cnt == 0) |
2646 | gdth_set_sema0(ha); | 2688 | gdth_set_sema0(ha); |
2647 | 2689 | ||
2690 | cmndinfo = gdth_cmnd_priv(scp); | ||
2648 | /* fill command */ | 2691 | /* fill command */ |
2649 | if (scp->SCp.sent_command != -1) { | 2692 | if (scp->SCp.sent_command != -1) { |
2650 | cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ | 2693 | cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ |
@@ -2668,9 +2711,8 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2668 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; | 2711 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; |
2669 | sense_paddr = pci_map_page(ha->pdev,page,offset, | 2712 | sense_paddr = pci_map_page(ha->pdev,page,offset, |
2670 | 16,PCI_DMA_FROMDEVICE); | 2713 | 16,PCI_DMA_FROMDEVICE); |
2671 | *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; | 2714 | |
2672 | /* high part, if 64bit */ | 2715 | cmndinfo->sense_paddr = sense_paddr; |
2673 | *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); | ||
2674 | cmdp->OpCode = GDT_WRITE; /* always */ | 2716 | cmdp->OpCode = GDT_WRITE; /* always */ |
2675 | cmdp->BoardNode = LOCALBOARD; | 2717 | cmdp->BoardNode = LOCALBOARD; |
2676 | if (mode64) { | 2718 | if (mode64) { |
@@ -3271,6 +3313,7 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | |||
3271 | gdth_msg_str *msg; | 3313 | gdth_msg_str *msg; |
3272 | gdth_cmd_str *cmdp; | 3314 | gdth_cmd_str *cmdp; |
3273 | unchar b, t; | 3315 | unchar b, t; |
3316 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
3274 | 3317 | ||
3275 | cmdp = ha->pccb; | 3318 | cmdp = ha->pccb; |
3276 | TRACE(("gdth_sync_event() serv %d status %d\n", | 3319 | TRACE(("gdth_sync_event() serv %d status %d\n", |
@@ -3364,14 +3407,9 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | |||
3364 | else if (scp->SCp.Status == GDTH_MAP_SINGLE) | 3407 | else if (scp->SCp.Status == GDTH_MAP_SINGLE) |
3365 | pci_unmap_page(ha->pdev,scp->SCp.dma_handle, | 3408 | pci_unmap_page(ha->pdev,scp->SCp.dma_handle, |
3366 | scp->request_bufflen,scp->SCp.Message); | 3409 | scp->request_bufflen,scp->SCp.Message); |
3367 | if (scp->SCp.buffer) { | 3410 | if (cmndinfo->sense_paddr) |
3368 | dma_addr_t addr; | 3411 | pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, |
3369 | addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; | 3412 | PCI_DMA_FROMDEVICE); |
3370 | if (scp->host_scribble) | ||
3371 | addr += (dma_addr_t) | ||
3372 | ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); | ||
3373 | pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); | ||
3374 | } | ||
3375 | 3413 | ||
3376 | if (ha->status == S_OK) { | 3414 | if (ha->status == S_OK) { |
3377 | scp->SCp.Status = S_OK; | 3415 | scp->SCp.Status = S_OK; |
@@ -3450,7 +3488,7 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | |||
3450 | scp->sense_buffer[2] = NOT_READY; | 3488 | scp->sense_buffer[2] = NOT_READY; |
3451 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 3489 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
3452 | } | 3490 | } |
3453 | if (!IS_GDTH_INTERNAL_CMD(scp)) { | 3491 | if (!cmndinfo->internal_command) { |
3454 | ha->dvr.size = sizeof(ha->dvr.eu.sync); | 3492 | ha->dvr.size = sizeof(ha->dvr.eu.sync); |
3455 | ha->dvr.eu.sync.ionode = ha->hanum; | 3493 | ha->dvr.eu.sync.ionode = ha->hanum; |
3456 | ha->dvr.eu.sync.service = service; | 3494 | ha->dvr.eu.sync.service = service; |
@@ -3995,28 +4033,33 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, | |||
3995 | void (*done)(struct scsi_cmnd *)) | 4033 | void (*done)(struct scsi_cmnd *)) |
3996 | { | 4034 | { |
3997 | gdth_ha_str *ha = shost_priv(scp->device->host); | 4035 | gdth_ha_str *ha = shost_priv(scp->device->host); |
3998 | int priority; | 4036 | struct gdth_cmndinfo *cmndinfo; |
3999 | 4037 | ||
4000 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); | 4038 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); |
4001 | 4039 | ||
4040 | cmndinfo = gdth_get_cmndinfo(ha); | ||
4041 | BUG_ON(!cmndinfo); | ||
4042 | |||
4002 | scp->scsi_done = done; | 4043 | scp->scsi_done = done; |
4044 | gdth_update_timeout(scp, scp->timeout_per_command * 6); | ||
4045 | scp->SCp.this_residual = DEFAULT_PRI; | ||
4046 | return __gdth_queuecommand(ha, scp, cmndinfo); | ||
4047 | } | ||
4048 | |||
4049 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
4050 | struct gdth_cmndinfo *cmndinfo) | ||
4051 | { | ||
4052 | scp->host_scribble = (unsigned char *)cmndinfo; | ||
4003 | scp->SCp.have_data_in = 1; | 4053 | scp->SCp.have_data_in = 1; |
4004 | scp->SCp.phase = -1; | 4054 | scp->SCp.phase = -1; |
4005 | scp->SCp.sent_command = -1; | 4055 | scp->SCp.sent_command = -1; |
4006 | scp->SCp.Status = GDTH_MAP_NONE; | 4056 | scp->SCp.Status = GDTH_MAP_NONE; |
4007 | scp->SCp.buffer = (struct scatterlist *)NULL; | ||
4008 | 4057 | ||
4009 | #ifdef GDTH_STATISTICS | 4058 | #ifdef GDTH_STATISTICS |
4010 | ++act_ios; | 4059 | ++act_ios; |
4011 | #endif | 4060 | #endif |
4012 | 4061 | ||
4013 | priority = DEFAULT_PRI; | 4062 | gdth_putq(ha, scp, scp->SCp.this_residual); |
4014 | if (IS_GDTH_INTERNAL_CMD(scp)) | ||
4015 | priority = scp->SCp.this_residual; | ||
4016 | else | ||
4017 | gdth_update_timeout(scp, scp->timeout_per_command * 6); | ||
4018 | |||
4019 | gdth_putq(ha, scp, priority); | ||
4020 | gdth_next(ha); | 4063 | gdth_next(ha); |
4021 | return 0; | 4064 | return 0; |
4022 | } | 4065 | } |