Home | History | Annotate | Download | only in EhciDxe
      1 /** @file
      2 
      3     This file contains URB request, each request is warpped in a
      4     URB (Usb Request Block).
      5 
      6 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions of the BSD License
      9 which accompanies this distribution.  The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include "Ehci.h"
     18 
     19 
     20 /**
     21   Create a single QTD to hold the data.
     22 
     23   @param  Ehc                   The EHCI device.
     24   @param  Data                  The cpu memory address of current data not associated with a QTD.
     25   @param  DataPhy               The pci bus address of current data not associated with a QTD.
     26   @param  DataLen               The length of the data.
     27   @param  PktId                 Packet ID to use in the QTD.
     28   @param  Toggle                Data toggle to use in the QTD.
     29   @param  MaxPacket             Maximu packet length of the endpoint.
     30 
     31   @return Created QTD or NULL if failed to create one.
     32 
     33 **/
     34 EHC_QTD *
     35 EhcCreateQtd (
     36   IN USB2_HC_DEV          *Ehc,
     37   IN UINT8                *Data,
     38   IN UINT8                *DataPhy,
     39   IN UINTN                DataLen,
     40   IN UINT8                PktId,
     41   IN UINT8                Toggle,
     42   IN UINTN                MaxPacket
     43   )
     44 {
     45   EHC_QTD                 *Qtd;
     46   QTD_HW                  *QtdHw;
     47   UINTN                   Index;
     48   UINTN                   Len;
     49   UINTN                   ThisBufLen;
     50 
     51   ASSERT (Ehc != NULL);
     52 
     53   Qtd = UsbHcAllocateMem (Ehc->MemPool, sizeof (EHC_QTD));
     54 
     55   if (Qtd == NULL) {
     56     return NULL;
     57   }
     58 
     59   Qtd->Signature    = EHC_QTD_SIG;
     60   Qtd->Data         = Data;
     61   Qtd->DataLen      = 0;
     62 
     63   InitializeListHead (&Qtd->QtdList);
     64 
     65   QtdHw             = &Qtd->QtdHw;
     66   QtdHw->NextQtd    = QTD_LINK (NULL, TRUE);
     67   QtdHw->AltNext    = QTD_LINK (NULL, TRUE);
     68   QtdHw->Status     = QTD_STAT_ACTIVE;
     69   QtdHw->Pid        = PktId;
     70   QtdHw->ErrCnt     = QTD_MAX_ERR;
     71   QtdHw->Ioc        = 0;
     72   QtdHw->TotalBytes = 0;
     73   QtdHw->DataToggle = Toggle;
     74 
     75   //
     76   // Fill in the buffer points
     77   //
     78   if (Data != NULL) {
     79     Len = 0;
     80 
     81     for (Index = 0; Index <= QTD_MAX_BUFFER; Index++) {
     82       //
     83       // Set the buffer point (Check page 41 EHCI Spec 1.0). No need to
     84       // compute the offset and clear Reserved fields. This is already
     85       // done in the data point.
     86       //
     87       QtdHw->Page[Index]      = EHC_LOW_32BIT (DataPhy);
     88       QtdHw->PageHigh[Index]  = EHC_HIGH_32BIT (DataPhy);
     89 
     90       ThisBufLen              = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK);
     91 
     92       if (Len + ThisBufLen >= DataLen) {
     93         Len = DataLen;
     94         break;
     95       }
     96 
     97       Len += ThisBufLen;
     98       Data += ThisBufLen;
     99       DataPhy += ThisBufLen;
    100     }
    101 
    102     //
    103     // Need to fix the last pointer if the Qtd can't hold all the
    104     // user's data to make sure that the length is in the unit of
    105     // max packets. If it can hold all the data, there is no such
    106     // need.
    107     //
    108     if (Len < DataLen) {
    109       Len = Len - Len % MaxPacket;
    110     }
    111 
    112     QtdHw->TotalBytes = (UINT32) Len;
    113     Qtd->DataLen      = Len;
    114   }
    115 
    116   return Qtd;
    117 }
    118 
    119 
    120 
    121 /**
    122   Initialize the queue head for interrupt transfer,
    123   that is, initialize the following three fields:
    124   1. SplitXState in the Status field
    125   2. Microframe S-mask
    126   3. Microframe C-mask
    127 
    128   @param  Ep                    The queue head's related endpoint.
    129   @param  QhHw                  The queue head to initialize.
    130 
    131 **/
    132 VOID
    133 EhcInitIntQh (
    134   IN USB_ENDPOINT         *Ep,
    135   IN QH_HW                *QhHw
    136   )
    137 {
    138   //
    139   // Because UEFI interface can't utilitize an endpoint with
    140   // poll rate faster than 1ms, only need to set one bit in
    141   // the queue head. simple. But it may be changed later. If
    142   // sub-1ms interrupt is supported, need to update the S-Mask
    143   // here
    144   //
    145   if (Ep->DevSpeed == EFI_USB_SPEED_HIGH) {
    146     QhHw->SMask = QH_MICROFRAME_0;
    147     return ;
    148   }
    149 
    150   //
    151   // For low/full speed device, the transfer must go through
    152   // the split transaction. Need to update three fields
    153   // 1. SplitXState in the status
    154   // 2. Microframe S-Mask
    155   // 3. Microframe C-Mask
    156   // UEFI USB doesn't exercise admission control. It simplely
    157   // schedule the high speed transactions in microframe 0, and
    158   // full/low speed transactions at microframe 1. This also
    159   // avoid the use of FSTN.
    160   //
    161   QhHw->SMask = QH_MICROFRAME_1;
    162   QhHw->CMask = QH_MICROFRAME_3 | QH_MICROFRAME_4 | QH_MICROFRAME_5;
    163 }
    164 
    165 
    166 
    167 /**
    168   Allocate and initialize a EHCI queue head.
    169 
    170   @param  Ehci                  The EHCI device.
    171   @param  Ep                    The endpoint to create queue head for.
    172 
    173   @return Created queue head or NULL if failed to create one.
    174 
    175 **/
    176 EHC_QH *
    177 EhcCreateQh (
    178   IN USB2_HC_DEV          *Ehci,
    179   IN USB_ENDPOINT         *Ep
    180   )
    181 {
    182   EHC_QH                  *Qh;
    183   QH_HW                   *QhHw;
    184 
    185   Qh = UsbHcAllocateMem (Ehci->MemPool, sizeof (EHC_QH));
    186 
    187   if (Qh == NULL) {
    188     return NULL;
    189   }
    190 
    191   Qh->Signature       = EHC_QH_SIG;
    192   Qh->NextQh          = NULL;
    193   Qh->Interval        = Ep->PollRate;
    194 
    195   InitializeListHead (&Qh->Qtds);
    196 
    197   QhHw                = &Qh->QhHw;
    198   QhHw->HorizonLink   = QH_LINK (NULL, 0, TRUE);
    199   QhHw->DeviceAddr    = Ep->DevAddr;
    200   QhHw->Inactive      = 0;
    201   QhHw->EpNum         = Ep->EpAddr;
    202   QhHw->EpSpeed       = Ep->DevSpeed;
    203   QhHw->DtCtrl        = 0;
    204   QhHw->ReclaimHead   = 0;
    205   QhHw->MaxPacketLen  = (UINT32) Ep->MaxPacket;
    206   QhHw->CtrlEp        = 0;
    207   QhHw->NakReload     = QH_NAK_RELOAD;
    208   QhHw->HubAddr       = Ep->HubAddr;
    209   QhHw->PortNum       = Ep->HubPort;
    210   QhHw->Multiplier    = 1;
    211   QhHw->DataToggle    = Ep->Toggle;
    212 
    213   if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
    214     QhHw->Status |= QTD_STAT_DO_SS;
    215   }
    216 
    217   switch (Ep->Type) {
    218   case EHC_CTRL_TRANSFER:
    219     //
    220     // Special initialization for the control transfer:
    221     // 1. Control transfer initialize data toggle from each QTD
    222     // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint.
    223     //
    224     QhHw->DtCtrl = 1;
    225 
    226     if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
    227       QhHw->CtrlEp = 1;
    228     }
    229     break;
    230 
    231   case EHC_INT_TRANSFER_ASYNC:
    232   case EHC_INT_TRANSFER_SYNC:
    233     //
    234     // Special initialization for the interrupt transfer
    235     // to set the S-Mask and C-Mask
    236     //
    237     QhHw->NakReload = 0;
    238     EhcInitIntQh (Ep, QhHw);
    239     break;
    240 
    241   case EHC_BULK_TRANSFER:
    242     if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) {
    243       QhHw->Status |= QTD_STAT_DO_PING;
    244     }
    245 
    246     break;
    247   }
    248 
    249   return Qh;
    250 }
    251 
    252 
    253 /**
    254   Convert the poll interval from application to that
    255   be used by EHCI interface data structure. Only need
    256   to get the max 2^n that is less than interval. UEFI
    257   can't support high speed endpoint with a interval less
    258   than 8 microframe because interval is specified in
    259   the unit of ms (millisecond).
    260 
    261   @param  Interval              The interval to convert.
    262 
    263   @return The converted interval.
    264 
    265 **/
    266 UINTN
    267 EhcConvertPollRate (
    268   IN  UINTN               Interval
    269   )
    270 {
    271   UINTN                   BitCount;
    272 
    273   if (Interval == 0) {
    274     return 1;
    275   }
    276 
    277   //
    278   // Find the index (1 based) of the highest non-zero bit
    279   //
    280   BitCount = 0;
    281 
    282   while (Interval != 0) {
    283     Interval >>= 1;
    284     BitCount++;
    285   }
    286 
    287   return (UINTN)1 << (BitCount - 1);
    288 }
    289 
    290 
    291 /**
    292   Free a list of QTDs.
    293 
    294   @param  Ehc                   The EHCI device.
    295   @param  Qtds                  The list head of the QTD.
    296 
    297 **/
    298 VOID
    299 EhcFreeQtds (
    300   IN USB2_HC_DEV          *Ehc,
    301   IN LIST_ENTRY           *Qtds
    302   )
    303 {
    304   LIST_ENTRY              *Entry;
    305   LIST_ENTRY              *Next;
    306   EHC_QTD                 *Qtd;
    307 
    308   EFI_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) {
    309     Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
    310 
    311     RemoveEntryList (&Qtd->QtdList);
    312     UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (EHC_QTD));
    313   }
    314 }
    315 
    316 
    317 /**
    318   Free an allocated URB. It is possible for it to be partially inited.
    319 
    320   @param  Ehc                   The EHCI device.
    321   @param  Urb                   The URB to free.
    322 
    323 **/
    324 VOID
    325 EhcFreeUrb (
    326   IN USB2_HC_DEV          *Ehc,
    327   IN URB                  *Urb
    328   )
    329 {
    330   EFI_PCI_IO_PROTOCOL       *PciIo;
    331 
    332   PciIo = Ehc->PciIo;
    333 
    334   if (Urb->RequestPhy != NULL) {
    335     PciIo->Unmap (PciIo, Urb->RequestMap);
    336   }
    337 
    338   if (Urb->DataMap != NULL) {
    339     PciIo->Unmap (PciIo, Urb->DataMap);
    340   }
    341 
    342   if (Urb->Qh != NULL) {
    343     //
    344     // Ensure that this queue head has been unlinked from the
    345     // schedule data structures. Free all the associated QTDs
    346     //
    347     EhcFreeQtds (Ehc, &Urb->Qh->Qtds);
    348     UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (EHC_QH));
    349   }
    350 
    351   gBS->FreePool (Urb);
    352 }
    353 
    354 
    355 /**
    356   Create a list of QTDs for the URB.
    357 
    358   @param  Ehc                   The EHCI device.
    359   @param  Urb                   The URB to create QTDs for.
    360 
    361   @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for QTD.
    362   @retval EFI_SUCCESS           The QTDs are allocated for the URB.
    363 
    364 **/
    365 EFI_STATUS
    366 EhcCreateQtds (
    367   IN USB2_HC_DEV          *Ehc,
    368   IN URB                  *Urb
    369   )
    370 {
    371   USB_ENDPOINT            *Ep;
    372   EHC_QH                  *Qh;
    373   EHC_QTD                 *Qtd;
    374   EHC_QTD                 *StatusQtd;
    375   EHC_QTD                 *NextQtd;
    376   LIST_ENTRY              *Entry;
    377   UINT32                  AlterNext;
    378   UINT8                   Toggle;
    379   UINTN                   Len;
    380   UINT8                   Pid;
    381   EFI_PHYSICAL_ADDRESS    PhyAddr;
    382 
    383   ASSERT ((Urb != NULL) && (Urb->Qh != NULL));
    384 
    385   //
    386   // EHCI follows the alternet next QTD pointer if it meets
    387   // a short read and the AlterNext pointer is valid. UEFI
    388   // EHCI driver should terminate the transfer except the
    389   // control transfer.
    390   //
    391   Toggle    = 0;
    392   Qh        = Urb->Qh;
    393   Ep        = &Urb->Ep;
    394   StatusQtd = NULL;
    395   AlterNext = QTD_LINK (NULL, TRUE);
    396 
    397   PhyAddr   = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));
    398   if (Ep->Direction == EfiUsbDataIn) {
    399     AlterNext = QTD_LINK (PhyAddr, FALSE);
    400   }
    401 
    402   //
    403   // Build the Setup and status packets for control transfer
    404   //
    405   if (Urb->Ep.Type == EHC_CTRL_TRANSFER) {
    406     Len = sizeof (EFI_USB_DEVICE_REQUEST);
    407     Qtd = EhcCreateQtd (Ehc, (UINT8 *)Urb->Request, (UINT8 *)Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket);
    408 
    409     if (Qtd == NULL) {
    410       return EFI_OUT_OF_RESOURCES;
    411     }
    412 
    413     InsertTailList (&Qh->Qtds, &Qtd->QtdList);
    414 
    415     //
    416     // Create the status packet now. Set the AlterNext to it. So, when
    417     // EHCI meets a short control read, it can resume at the status stage.
    418     // Use the opposite direction of the data stage, or IN if there is
    419     // no data stage.
    420     //
    421     if (Ep->Direction == EfiUsbDataIn) {
    422       Pid = QTD_PID_OUTPUT;
    423     } else {
    424       Pid = QTD_PID_INPUT;
    425     }
    426 
    427     StatusQtd = EhcCreateQtd (Ehc, NULL, NULL, 0, Pid, 1, Ep->MaxPacket);
    428 
    429     if (StatusQtd == NULL) {
    430       goto ON_ERROR;
    431     }
    432 
    433     if (Ep->Direction == EfiUsbDataIn) {
    434       PhyAddr   = UsbHcGetPciAddressForHostMem (Ehc->MemPool, StatusQtd, sizeof (EHC_QTD));
    435       AlterNext = QTD_LINK (PhyAddr, FALSE);
    436     }
    437 
    438     Toggle = 1;
    439   }
    440 
    441   //
    442   // Build the data packets for all the transfers
    443   //
    444   if (Ep->Direction == EfiUsbDataIn) {
    445     Pid = QTD_PID_INPUT;
    446   } else {
    447     Pid = QTD_PID_OUTPUT;
    448   }
    449 
    450   Qtd = NULL;
    451   Len = 0;
    452 
    453   while (Len < Urb->DataLen) {
    454     Qtd = EhcCreateQtd (
    455             Ehc,
    456             (UINT8 *) Urb->Data + Len,
    457             (UINT8 *) Urb->DataPhy + Len,
    458             Urb->DataLen - Len,
    459             Pid,
    460             Toggle,
    461             Ep->MaxPacket
    462             );
    463 
    464     if (Qtd == NULL) {
    465       goto ON_ERROR;
    466     }
    467 
    468     Qtd->QtdHw.AltNext = AlterNext;
    469     InsertTailList (&Qh->Qtds, &Qtd->QtdList);
    470 
    471     //
    472     // Switch the Toggle bit if odd number of packets are included in the QTD.
    473     //
    474     if (((Qtd->DataLen + Ep->MaxPacket - 1) / Ep->MaxPacket) % 2) {
    475       Toggle = (UINT8) (1 - Toggle);
    476     }
    477 
    478     Len += Qtd->DataLen;
    479   }
    480 
    481   //
    482   // Insert the status packet for control transfer
    483   //
    484   if (Ep->Type == EHC_CTRL_TRANSFER) {
    485     InsertTailList (&Qh->Qtds, &StatusQtd->QtdList);
    486   }
    487 
    488   //
    489   // OK, all the QTDs needed are created. Now, fix the NextQtd point
    490   //
    491   EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) {
    492     Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
    493 
    494     //
    495     // break if it is the last entry on the list
    496     //
    497     if (Entry->ForwardLink == &Qh->Qtds) {
    498       break;
    499     }
    500 
    501     NextQtd             = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList);
    502     PhyAddr             = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));
    503     Qtd->QtdHw.NextQtd  = QTD_LINK (PhyAddr, FALSE);
    504   }
    505 
    506   //
    507   // Link the QTDs to the queue head
    508   //
    509   NextQtd           = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList);
    510   PhyAddr           = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));
    511   Qh->QhHw.NextQtd  = QTD_LINK (PhyAddr, FALSE);
    512   return EFI_SUCCESS;
    513 
    514 ON_ERROR:
    515   EhcFreeQtds (Ehc, &Qh->Qtds);
    516   return EFI_OUT_OF_RESOURCES;
    517 }
    518 
    519 
    520 /**
    521   Create a new URB and its associated QTD.
    522 
    523   @param  Ehc                   The EHCI device.
    524   @param  DevAddr               The device address.
    525   @param  EpAddr                Endpoint addrress & its direction.
    526   @param  DevSpeed              The device speed.
    527   @param  Toggle                Initial data toggle to use.
    528   @param  MaxPacket             The max packet length of the endpoint.
    529   @param  Hub                   The transaction translator to use.
    530   @param  Type                  The transaction type.
    531   @param  Request               The standard USB request for control transfer.
    532   @param  Data                  The user data to transfer.
    533   @param  DataLen               The length of data buffer.
    534   @param  Callback              The function to call when data is transferred.
    535   @param  Context               The context to the callback.
    536   @param  Interval              The interval for interrupt transfer.
    537 
    538   @return Created URB or NULL.
    539 
    540 **/
    541 URB *
    542 EhcCreateUrb (
    543   IN USB2_HC_DEV                        *Ehc,
    544   IN UINT8                              DevAddr,
    545   IN UINT8                              EpAddr,
    546   IN UINT8                              DevSpeed,
    547   IN UINT8                              Toggle,
    548   IN UINTN                              MaxPacket,
    549   IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub,
    550   IN UINTN                              Type,
    551   IN EFI_USB_DEVICE_REQUEST             *Request,
    552   IN VOID                               *Data,
    553   IN UINTN                              DataLen,
    554   IN EFI_ASYNC_USB_TRANSFER_CALLBACK    Callback,
    555   IN VOID                               *Context,
    556   IN UINTN                              Interval
    557   )
    558 {
    559   USB_ENDPOINT                  *Ep;
    560   EFI_PHYSICAL_ADDRESS          PhyAddr;
    561   EFI_PCI_IO_PROTOCOL_OPERATION MapOp;
    562   EFI_PCI_IO_PROTOCOL           *PciIo;
    563   EFI_STATUS                    Status;
    564   UINTN                         Len;
    565   URB                           *Urb;
    566   VOID                          *Map;
    567 
    568   Urb = AllocateZeroPool (sizeof (URB));
    569 
    570   if (Urb == NULL) {
    571     return NULL;
    572   }
    573 
    574   Urb->Signature  = EHC_URB_SIG;
    575   InitializeListHead (&Urb->UrbList);
    576 
    577   Ep              = &Urb->Ep;
    578   Ep->DevAddr     = DevAddr;
    579   Ep->EpAddr      = (UINT8) (EpAddr & 0x0F);
    580   Ep->Direction   = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut);
    581   Ep->DevSpeed    = DevSpeed;
    582   Ep->MaxPacket   = MaxPacket;
    583 
    584   Ep->HubAddr     = 0;
    585   Ep->HubPort     = 0;
    586 
    587   if (DevSpeed != EFI_USB_SPEED_HIGH) {
    588     ASSERT (Hub != NULL);
    589 
    590     Ep->HubAddr   = Hub->TranslatorHubAddress;
    591     Ep->HubPort   = Hub->TranslatorPortNumber;
    592   }
    593 
    594   Ep->Toggle      = Toggle;
    595   Ep->Type        = Type;
    596   Ep->PollRate    = EhcConvertPollRate (Interval);
    597 
    598   Urb->Request    = Request;
    599   Urb->Data       = Data;
    600   Urb->DataLen    = DataLen;
    601   Urb->Callback   = Callback;
    602   Urb->Context    = Context;
    603 
    604   PciIo           = Ehc->PciIo;
    605   Urb->Qh         = EhcCreateQh (Ehc, &Urb->Ep);
    606 
    607   if (Urb->Qh == NULL) {
    608     goto ON_ERROR;
    609   }
    610 
    611   //
    612   // Map the request and user data
    613   //
    614   if (Request != NULL) {
    615     Len     = sizeof (EFI_USB_DEVICE_REQUEST);
    616     MapOp   = EfiPciIoOperationBusMasterRead;
    617     Status  = PciIo->Map (PciIo, MapOp, Request, &Len, &PhyAddr, &Map);
    618 
    619     if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
    620       goto ON_ERROR;
    621     }
    622 
    623     Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr);
    624     Urb->RequestMap = Map;
    625   }
    626 
    627   if (Data != NULL) {
    628     Len     = DataLen;
    629 
    630     if (Ep->Direction == EfiUsbDataIn) {
    631       MapOp = EfiPciIoOperationBusMasterWrite;
    632     } else {
    633       MapOp = EfiPciIoOperationBusMasterRead;
    634     }
    635 
    636     Status  = PciIo->Map (PciIo, MapOp, Data, &Len, &PhyAddr, &Map);
    637 
    638     if (EFI_ERROR (Status) || (Len != DataLen)) {
    639       goto ON_ERROR;
    640     }
    641 
    642     Urb->DataPhy  = (VOID *) ((UINTN) PhyAddr);
    643     Urb->DataMap  = Map;
    644   }
    645 
    646   Status = EhcCreateQtds (Ehc, Urb);
    647 
    648   if (EFI_ERROR (Status)) {
    649     goto ON_ERROR;
    650   }
    651 
    652   return Urb;
    653 
    654 ON_ERROR:
    655   EhcFreeUrb (Ehc, Urb);
    656   return NULL;
    657 }
    658